xref: /petsc/src/mat/interface/matrix.c (revision 49a6f2e5440bbcbd382a01c535bb68c01842b385)
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   if (viewf) {
4432     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4433   }
4434 
4435   B->stencil.dim = mat->stencil.dim;
4436   B->stencil.noc = mat->stencil.noc;
4437   for (i=0; i<=mat->stencil.dim; i++) {
4438     B->stencil.dims[i]   = mat->stencil.dims[i];
4439     B->stencil.starts[i] = mat->stencil.starts[i];
4440   }
4441 
4442   B->nooffproczerorows = mat->nooffproczerorows;
4443   B->nooffprocentries  = mat->nooffprocentries;
4444 
4445   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4446   if (dm) {
4447     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4448   }
4449   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4450   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4451   PetscFunctionReturn(0);
4452 }
4453 
4454 /*@
4455    MatGetDiagonal - Gets the diagonal of a matrix.
4456 
4457    Logically Collective on Mat and Vec
4458 
4459    Input Parameters:
4460 +  mat - the matrix
4461 -  v - the vector for storing the diagonal
4462 
4463    Output Parameter:
4464 .  v - the diagonal of the matrix
4465 
4466    Level: intermediate
4467 
4468    Note:
4469    Currently only correct in parallel for square matrices.
4470 
4471    Concepts: matrices^accessing diagonals
4472 
4473 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4474 @*/
4475 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4476 {
4477   PetscErrorCode ierr;
4478 
4479   PetscFunctionBegin;
4480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4481   PetscValidType(mat,1);
4482   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4483   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4484   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4485   MatCheckPreallocated(mat,1);
4486 
4487   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4488   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4489   PetscFunctionReturn(0);
4490 }
4491 
4492 /*@C
4493    MatGetRowMin - Gets the minimum value (of the real part) of each
4494         row of the matrix
4495 
4496    Logically Collective on Mat and Vec
4497 
4498    Input Parameters:
4499 .  mat - the matrix
4500 
4501    Output Parameter:
4502 +  v - the vector for storing the maximums
4503 -  idx - the indices of the column found for each row (optional)
4504 
4505    Level: intermediate
4506 
4507    Notes: The result of this call are the same as if one converted the matrix to dense format
4508       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4509 
4510     This code is only implemented for a couple of matrix formats.
4511 
4512    Concepts: matrices^getting row maximums
4513 
4514 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4515           MatGetRowMax()
4516 @*/
4517 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4518 {
4519   PetscErrorCode ierr;
4520 
4521   PetscFunctionBegin;
4522   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4523   PetscValidType(mat,1);
4524   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4525   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4526   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4527   MatCheckPreallocated(mat,1);
4528 
4529   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4530   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4531   PetscFunctionReturn(0);
4532 }
4533 
4534 /*@C
4535    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4536         row of the matrix
4537 
4538    Logically Collective on Mat and Vec
4539 
4540    Input Parameters:
4541 .  mat - the matrix
4542 
4543    Output Parameter:
4544 +  v - the vector for storing the minimums
4545 -  idx - the indices of the column found for each row (or NULL if not needed)
4546 
4547    Level: intermediate
4548 
4549    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4550     row is 0 (the first column).
4551 
4552     This code is only implemented for a couple of matrix formats.
4553 
4554    Concepts: matrices^getting row maximums
4555 
4556 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4557 @*/
4558 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4559 {
4560   PetscErrorCode ierr;
4561 
4562   PetscFunctionBegin;
4563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4564   PetscValidType(mat,1);
4565   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4566   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4567   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4568   MatCheckPreallocated(mat,1);
4569   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4570 
4571   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4572   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4573   PetscFunctionReturn(0);
4574 }
4575 
4576 /*@C
4577    MatGetRowMax - Gets the maximum value (of the real part) of each
4578         row of the matrix
4579 
4580    Logically Collective on Mat and Vec
4581 
4582    Input Parameters:
4583 .  mat - the matrix
4584 
4585    Output Parameter:
4586 +  v - the vector for storing the maximums
4587 -  idx - the indices of the column found for each row (optional)
4588 
4589    Level: intermediate
4590 
4591    Notes: The result of this call are the same as if one converted the matrix to dense format
4592       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4593 
4594     This code is only implemented for a couple of matrix formats.
4595 
4596    Concepts: matrices^getting row maximums
4597 
4598 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4599 @*/
4600 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4601 {
4602   PetscErrorCode ierr;
4603 
4604   PetscFunctionBegin;
4605   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4606   PetscValidType(mat,1);
4607   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4608   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4609   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4610   MatCheckPreallocated(mat,1);
4611 
4612   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4613   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4614   PetscFunctionReturn(0);
4615 }
4616 
4617 /*@C
4618    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4619         row of the matrix
4620 
4621    Logically Collective on Mat and Vec
4622 
4623    Input Parameters:
4624 .  mat - the matrix
4625 
4626    Output Parameter:
4627 +  v - the vector for storing the maximums
4628 -  idx - the indices of the column found for each row (or NULL if not needed)
4629 
4630    Level: intermediate
4631 
4632    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4633     row is 0 (the first column).
4634 
4635     This code is only implemented for a couple of matrix formats.
4636 
4637    Concepts: matrices^getting row maximums
4638 
4639 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4640 @*/
4641 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4642 {
4643   PetscErrorCode ierr;
4644 
4645   PetscFunctionBegin;
4646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4647   PetscValidType(mat,1);
4648   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4649   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4650   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4651   MatCheckPreallocated(mat,1);
4652   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4653 
4654   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4655   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4656   PetscFunctionReturn(0);
4657 }
4658 
4659 /*@
4660    MatGetRowSum - Gets the sum of each row of the matrix
4661 
4662    Logically or Neighborhood Collective on Mat and Vec
4663 
4664    Input Parameters:
4665 .  mat - the matrix
4666 
4667    Output Parameter:
4668 .  v - the vector for storing the sum of rows
4669 
4670    Level: intermediate
4671 
4672    Notes: This code is slow since it is not currently specialized for different formats
4673 
4674    Concepts: matrices^getting row sums
4675 
4676 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4677 @*/
4678 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4679 {
4680   Vec            ones;
4681   PetscErrorCode ierr;
4682 
4683   PetscFunctionBegin;
4684   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4685   PetscValidType(mat,1);
4686   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4687   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4688   MatCheckPreallocated(mat,1);
4689   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4690   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4691   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4692   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4693   PetscFunctionReturn(0);
4694 }
4695 
4696 /*@
4697    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4698 
4699    Collective on Mat
4700 
4701    Input Parameter:
4702 +  mat - the matrix to transpose
4703 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4704 
4705    Output Parameters:
4706 .  B - the transpose
4707 
4708    Notes:
4709      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4710 
4711      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4712 
4713      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4714 
4715    Level: intermediate
4716 
4717    Concepts: matrices^transposing
4718 
4719 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4720 @*/
4721 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4722 {
4723   PetscErrorCode ierr;
4724 
4725   PetscFunctionBegin;
4726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4727   PetscValidType(mat,1);
4728   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4729   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4730   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4731   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4732   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4733   MatCheckPreallocated(mat,1);
4734 
4735   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4736   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4737   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4738   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4739   PetscFunctionReturn(0);
4740 }
4741 
4742 /*@
4743    MatIsTranspose - Test whether a matrix is another one's transpose,
4744         or its own, in which case it tests symmetry.
4745 
4746    Collective on Mat
4747 
4748    Input Parameter:
4749 +  A - the matrix to test
4750 -  B - the matrix to test against, this can equal the first parameter
4751 
4752    Output Parameters:
4753 .  flg - the result
4754 
4755    Notes:
4756    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4757    has a running time of the order of the number of nonzeros; the parallel
4758    test involves parallel copies of the block-offdiagonal parts of the matrix.
4759 
4760    Level: intermediate
4761 
4762    Concepts: matrices^transposing, matrix^symmetry
4763 
4764 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4765 @*/
4766 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4767 {
4768   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4769 
4770   PetscFunctionBegin;
4771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4772   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4773   PetscValidPointer(flg,3);
4774   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4775   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4776   *flg = PETSC_FALSE;
4777   if (f && g) {
4778     if (f == g) {
4779       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4780     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4781   } else {
4782     MatType mattype;
4783     if (!f) {
4784       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4785     } else {
4786       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4787     }
4788     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4789   }
4790   PetscFunctionReturn(0);
4791 }
4792 
4793 /*@
4794    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4795 
4796    Collective on Mat
4797 
4798    Input Parameter:
4799 +  mat - the matrix to transpose and complex conjugate
4800 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4801 
4802    Output Parameters:
4803 .  B - the Hermitian
4804 
4805    Level: intermediate
4806 
4807    Concepts: matrices^transposing, complex conjugatex
4808 
4809 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4810 @*/
4811 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4812 {
4813   PetscErrorCode ierr;
4814 
4815   PetscFunctionBegin;
4816   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4817 #if defined(PETSC_USE_COMPLEX)
4818   ierr = MatConjugate(*B);CHKERRQ(ierr);
4819 #endif
4820   PetscFunctionReturn(0);
4821 }
4822 
4823 /*@
4824    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4825 
4826    Collective on Mat
4827 
4828    Input Parameter:
4829 +  A - the matrix to test
4830 -  B - the matrix to test against, this can equal the first parameter
4831 
4832    Output Parameters:
4833 .  flg - the result
4834 
4835    Notes:
4836    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4837    has a running time of the order of the number of nonzeros; the parallel
4838    test involves parallel copies of the block-offdiagonal parts of the matrix.
4839 
4840    Level: intermediate
4841 
4842    Concepts: matrices^transposing, matrix^symmetry
4843 
4844 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4845 @*/
4846 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4847 {
4848   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4849 
4850   PetscFunctionBegin;
4851   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4852   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4853   PetscValidPointer(flg,3);
4854   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4855   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4856   if (f && g) {
4857     if (f==g) {
4858       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4859     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4860   }
4861   PetscFunctionReturn(0);
4862 }
4863 
4864 /*@
4865    MatPermute - Creates a new matrix with rows and columns permuted from the
4866    original.
4867 
4868    Collective on Mat
4869 
4870    Input Parameters:
4871 +  mat - the matrix to permute
4872 .  row - row permutation, each processor supplies only the permutation for its rows
4873 -  col - column permutation, each processor supplies only the permutation for its columns
4874 
4875    Output Parameters:
4876 .  B - the permuted matrix
4877 
4878    Level: advanced
4879 
4880    Note:
4881    The index sets map from row/col of permuted matrix to row/col of original matrix.
4882    The index sets should be on the same communicator as Mat and have the same local sizes.
4883 
4884    Concepts: matrices^permuting
4885 
4886 .seealso: MatGetOrdering(), ISAllGather()
4887 
4888 @*/
4889 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4890 {
4891   PetscErrorCode ierr;
4892 
4893   PetscFunctionBegin;
4894   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4895   PetscValidType(mat,1);
4896   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4897   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4898   PetscValidPointer(B,4);
4899   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4900   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4901   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4902   MatCheckPreallocated(mat,1);
4903 
4904   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4905   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4906   PetscFunctionReturn(0);
4907 }
4908 
4909 /*@
4910    MatEqual - Compares two matrices.
4911 
4912    Collective on Mat
4913 
4914    Input Parameters:
4915 +  A - the first matrix
4916 -  B - the second matrix
4917 
4918    Output Parameter:
4919 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4920 
4921    Level: intermediate
4922 
4923    Concepts: matrices^equality between
4924 @*/
4925 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4926 {
4927   PetscErrorCode ierr;
4928 
4929   PetscFunctionBegin;
4930   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4931   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4932   PetscValidType(A,1);
4933   PetscValidType(B,2);
4934   PetscValidIntPointer(flg,3);
4935   PetscCheckSameComm(A,1,B,2);
4936   MatCheckPreallocated(B,2);
4937   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4938   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4939   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);
4940   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4941   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4942   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);
4943   MatCheckPreallocated(A,1);
4944 
4945   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4946   PetscFunctionReturn(0);
4947 }
4948 
4949 /*@C
4950    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4951    matrices that are stored as vectors.  Either of the two scaling
4952    matrices can be NULL.
4953 
4954    Collective on Mat
4955 
4956    Input Parameters:
4957 +  mat - the matrix to be scaled
4958 .  l - the left scaling vector (or NULL)
4959 -  r - the right scaling vector (or NULL)
4960 
4961    Notes:
4962    MatDiagonalScale() computes A = LAR, where
4963    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4964    The L scales the rows of the matrix, the R scales the columns of the matrix.
4965 
4966    Level: intermediate
4967 
4968    Concepts: matrices^diagonal scaling
4969    Concepts: diagonal scaling of matrices
4970 
4971 .seealso: MatScale(), MatShift(), MatDiagonalSet()
4972 @*/
4973 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4974 {
4975   PetscErrorCode ierr;
4976 
4977   PetscFunctionBegin;
4978   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4979   PetscValidType(mat,1);
4980   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4981   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4982   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4983   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4984   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4985   MatCheckPreallocated(mat,1);
4986 
4987   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4988   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4989   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4990   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4991 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
4992   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
4993     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
4994   }
4995 #endif
4996   PetscFunctionReturn(0);
4997 }
4998 
4999 /*@
5000     MatScale - Scales all elements of a matrix by a given number.
5001 
5002     Logically Collective on Mat
5003 
5004     Input Parameters:
5005 +   mat - the matrix to be scaled
5006 -   a  - the scaling value
5007 
5008     Output Parameter:
5009 .   mat - the scaled matrix
5010 
5011     Level: intermediate
5012 
5013     Concepts: matrices^scaling all entries
5014 
5015 .seealso: MatDiagonalScale()
5016 @*/
5017 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5018 {
5019   PetscErrorCode ierr;
5020 
5021   PetscFunctionBegin;
5022   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5023   PetscValidType(mat,1);
5024   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5025   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5026   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5027   PetscValidLogicalCollectiveScalar(mat,a,2);
5028   MatCheckPreallocated(mat,1);
5029 
5030   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5031   if (a != (PetscScalar)1.0) {
5032     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5033     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5034 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5035     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5036       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5037     }
5038 #endif
5039   }
5040   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5041   PetscFunctionReturn(0);
5042 }
5043 
5044 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm)
5045 {
5046   PetscErrorCode ierr;
5047 
5048   PetscFunctionBegin;
5049   if (type == NORM_1 || type == NORM_INFINITY) {
5050     Vec l,r;
5051 
5052     ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr);
5053     if (type == NORM_INFINITY) {
5054       ierr = VecSet(r,1.);CHKERRQ(ierr);
5055       ierr = MatMult(A,r,l);CHKERRQ(ierr);
5056       ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr);
5057     } else {
5058       ierr = VecSet(l,1.);CHKERRQ(ierr);
5059       ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr);
5060       ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr);
5061     }
5062     ierr = VecDestroy(&l);CHKERRQ(ierr);
5063     ierr = VecDestroy(&r);CHKERRQ(ierr);
5064   } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type);
5065   PetscFunctionReturn(0);
5066 }
5067 
5068 /*@
5069    MatNorm - Calculates various norms of a matrix.
5070 
5071    Collective on Mat
5072 
5073    Input Parameters:
5074 +  mat - the matrix
5075 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5076 
5077    Output Parameters:
5078 .  nrm - the resulting norm
5079 
5080    Level: intermediate
5081 
5082    Concepts: matrices^norm
5083    Concepts: norm^of matrix
5084 @*/
5085 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5086 {
5087   PetscErrorCode ierr;
5088 
5089   PetscFunctionBegin;
5090   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5091   PetscValidType(mat,1);
5092   PetscValidLogicalCollectiveEnum(mat,type,2);
5093   PetscValidScalarPointer(nrm,3);
5094 
5095   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5096   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5097   MatCheckPreallocated(mat,1);
5098 
5099   if (!mat->ops->norm) {
5100     ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr);
5101   } else {
5102     ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5103   }
5104   PetscFunctionReturn(0);
5105 }
5106 
5107 /*
5108      This variable is used to prevent counting of MatAssemblyBegin() that
5109    are called from within a MatAssemblyEnd().
5110 */
5111 static PetscInt MatAssemblyEnd_InUse = 0;
5112 /*@
5113    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5114    be called after completing all calls to MatSetValues().
5115 
5116    Collective on Mat
5117 
5118    Input Parameters:
5119 +  mat - the matrix
5120 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5121 
5122    Notes:
5123    MatSetValues() generally caches the values.  The matrix is ready to
5124    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5125    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5126    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5127    using the matrix.
5128 
5129    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5130    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
5131    a global collective operation requring all processes that share the matrix.
5132 
5133    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5134    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5135    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5136 
5137    Level: beginner
5138 
5139    Concepts: matrices^assembling
5140 
5141 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5142 @*/
5143 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5144 {
5145   PetscErrorCode ierr;
5146 
5147   PetscFunctionBegin;
5148   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5149   PetscValidType(mat,1);
5150   MatCheckPreallocated(mat,1);
5151   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5152   if (mat->assembled) {
5153     mat->was_assembled = PETSC_TRUE;
5154     mat->assembled     = PETSC_FALSE;
5155   }
5156   if (!MatAssemblyEnd_InUse) {
5157     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5158     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5159     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5160   } else if (mat->ops->assemblybegin) {
5161     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5162   }
5163   PetscFunctionReturn(0);
5164 }
5165 
5166 /*@
5167    MatAssembled - Indicates if a matrix has been assembled and is ready for
5168      use; for example, in matrix-vector product.
5169 
5170    Not Collective
5171 
5172    Input Parameter:
5173 .  mat - the matrix
5174 
5175    Output Parameter:
5176 .  assembled - PETSC_TRUE or PETSC_FALSE
5177 
5178    Level: advanced
5179 
5180    Concepts: matrices^assembled?
5181 
5182 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5183 @*/
5184 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5185 {
5186   PetscFunctionBegin;
5187   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5188   PetscValidType(mat,1);
5189   PetscValidPointer(assembled,2);
5190   *assembled = mat->assembled;
5191   PetscFunctionReturn(0);
5192 }
5193 
5194 /*@
5195    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5196    be called after MatAssemblyBegin().
5197 
5198    Collective on Mat
5199 
5200    Input Parameters:
5201 +  mat - the matrix
5202 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5203 
5204    Options Database Keys:
5205 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5206 .  -mat_view ::ascii_info_detail - Prints more detailed info
5207 .  -mat_view - Prints matrix in ASCII format
5208 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5209 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5210 .  -display <name> - Sets display name (default is host)
5211 .  -draw_pause <sec> - Sets number of seconds to pause after display
5212 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5213 .  -viewer_socket_machine <machine> - Machine to use for socket
5214 .  -viewer_socket_port <port> - Port number to use for socket
5215 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5216 
5217    Notes:
5218    MatSetValues() generally caches the values.  The matrix is ready to
5219    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5220    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5221    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5222    using the matrix.
5223 
5224    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5225    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5226    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5227 
5228    Level: beginner
5229 
5230 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5231 @*/
5232 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5233 {
5234   PetscErrorCode  ierr;
5235   static PetscInt inassm = 0;
5236   PetscBool       flg    = PETSC_FALSE;
5237 
5238   PetscFunctionBegin;
5239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5240   PetscValidType(mat,1);
5241 
5242   inassm++;
5243   MatAssemblyEnd_InUse++;
5244   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5245     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5246     if (mat->ops->assemblyend) {
5247       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5248     }
5249     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5250   } else if (mat->ops->assemblyend) {
5251     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5252   }
5253 
5254   /* Flush assembly is not a true assembly */
5255   if (type != MAT_FLUSH_ASSEMBLY) {
5256     mat->assembled = PETSC_TRUE; mat->num_ass++;
5257   }
5258   mat->insertmode = NOT_SET_VALUES;
5259   MatAssemblyEnd_InUse--;
5260   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5261   if (!mat->symmetric_eternal) {
5262     mat->symmetric_set              = PETSC_FALSE;
5263     mat->hermitian_set              = PETSC_FALSE;
5264     mat->structurally_symmetric_set = PETSC_FALSE;
5265   }
5266 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5267   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5268     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5269   }
5270 #endif
5271   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5272     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5273 
5274     if (mat->checksymmetryonassembly) {
5275       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5276       if (flg) {
5277         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5278       } else {
5279         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5280       }
5281     }
5282     if (mat->nullsp && mat->checknullspaceonassembly) {
5283       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5284     }
5285   }
5286   inassm--;
5287   PetscFunctionReturn(0);
5288 }
5289 
5290 /*@
5291    MatSetOption - Sets a parameter option for a matrix. Some options
5292    may be specific to certain storage formats.  Some options
5293    determine how values will be inserted (or added). Sorted,
5294    row-oriented input will generally assemble the fastest. The default
5295    is row-oriented.
5296 
5297    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5298 
5299    Input Parameters:
5300 +  mat - the matrix
5301 .  option - the option, one of those listed below (and possibly others),
5302 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5303 
5304   Options Describing Matrix Structure:
5305 +    MAT_SPD - symmetric positive definite
5306 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5307 .    MAT_HERMITIAN - transpose is the complex conjugation
5308 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5309 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5310                             you set to be kept with all future use of the matrix
5311                             including after MatAssemblyBegin/End() which could
5312                             potentially change the symmetry structure, i.e. you
5313                             KNOW the matrix will ALWAYS have the property you set.
5314 
5315 
5316    Options For Use with MatSetValues():
5317    Insert a logically dense subblock, which can be
5318 .    MAT_ROW_ORIENTED - row-oriented (default)
5319 
5320    Note these options reflect the data you pass in with MatSetValues(); it has
5321    nothing to do with how the data is stored internally in the matrix
5322    data structure.
5323 
5324    When (re)assembling a matrix, we can restrict the input for
5325    efficiency/debugging purposes.  These options include:
5326 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5327 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5328 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5329 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5330 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5331 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5332         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5333         performance for very large process counts.
5334 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5335         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5336         functions, instead sending only neighbor messages.
5337 
5338    Notes:
5339    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5340 
5341    Some options are relevant only for particular matrix types and
5342    are thus ignored by others.  Other options are not supported by
5343    certain matrix types and will generate an error message if set.
5344 
5345    If using a Fortran 77 module to compute a matrix, one may need to
5346    use the column-oriented option (or convert to the row-oriented
5347    format).
5348 
5349    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5350    that would generate a new entry in the nonzero structure is instead
5351    ignored.  Thus, if memory has not alredy been allocated for this particular
5352    data, then the insertion is ignored. For dense matrices, in which
5353    the entire array is allocated, no entries are ever ignored.
5354    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5355 
5356    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5357    that would generate a new entry in the nonzero structure instead produces
5358    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
5359 
5360    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5361    that would generate a new entry that has not been preallocated will
5362    instead produce an error. (Currently supported for AIJ and BAIJ formats
5363    only.) This is a useful flag when debugging matrix memory preallocation.
5364    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5365 
5366    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5367    other processors should be dropped, rather than stashed.
5368    This is useful if you know that the "owning" processor is also
5369    always generating the correct matrix entries, so that PETSc need
5370    not transfer duplicate entries generated on another processor.
5371 
5372    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5373    searches during matrix assembly. When this flag is set, the hash table
5374    is created during the first Matrix Assembly. This hash table is
5375    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5376    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5377    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5378    supported by MATMPIBAIJ format only.
5379 
5380    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5381    are kept in the nonzero structure
5382 
5383    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5384    a zero location in the matrix
5385 
5386    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5387 
5388    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5389         zero row routines and thus improves performance for very large process counts.
5390 
5391    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5392         part of the matrix (since they should match the upper triangular part).
5393 
5394    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5395 
5396    Level: intermediate
5397 
5398    Concepts: matrices^setting options
5399 
5400 .seealso:  MatOption, Mat
5401 
5402 @*/
5403 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5404 {
5405   PetscErrorCode ierr;
5406 
5407   PetscFunctionBegin;
5408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5409   PetscValidType(mat,1);
5410   if (op > 0) {
5411     PetscValidLogicalCollectiveEnum(mat,op,2);
5412     PetscValidLogicalCollectiveBool(mat,flg,3);
5413   }
5414 
5415   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);
5416   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()");
5417 
5418   switch (op) {
5419   case MAT_NO_OFF_PROC_ENTRIES:
5420     mat->nooffprocentries = flg;
5421     PetscFunctionReturn(0);
5422     break;
5423   case MAT_SUBSET_OFF_PROC_ENTRIES:
5424     mat->subsetoffprocentries = flg;
5425     PetscFunctionReturn(0);
5426   case MAT_NO_OFF_PROC_ZERO_ROWS:
5427     mat->nooffproczerorows = flg;
5428     PetscFunctionReturn(0);
5429     break;
5430   case MAT_SPD:
5431     mat->spd_set = PETSC_TRUE;
5432     mat->spd     = flg;
5433     if (flg) {
5434       mat->symmetric                  = PETSC_TRUE;
5435       mat->structurally_symmetric     = PETSC_TRUE;
5436       mat->symmetric_set              = PETSC_TRUE;
5437       mat->structurally_symmetric_set = PETSC_TRUE;
5438     }
5439     break;
5440   case MAT_SYMMETRIC:
5441     mat->symmetric = flg;
5442     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5443     mat->symmetric_set              = PETSC_TRUE;
5444     mat->structurally_symmetric_set = flg;
5445 #if !defined(PETSC_USE_COMPLEX)
5446     mat->hermitian     = flg;
5447     mat->hermitian_set = PETSC_TRUE;
5448 #endif
5449     break;
5450   case MAT_HERMITIAN:
5451     mat->hermitian = flg;
5452     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5453     mat->hermitian_set              = PETSC_TRUE;
5454     mat->structurally_symmetric_set = flg;
5455 #if !defined(PETSC_USE_COMPLEX)
5456     mat->symmetric     = flg;
5457     mat->symmetric_set = PETSC_TRUE;
5458 #endif
5459     break;
5460   case MAT_STRUCTURALLY_SYMMETRIC:
5461     mat->structurally_symmetric     = flg;
5462     mat->structurally_symmetric_set = PETSC_TRUE;
5463     break;
5464   case MAT_SYMMETRY_ETERNAL:
5465     mat->symmetric_eternal = flg;
5466     break;
5467   case MAT_STRUCTURE_ONLY:
5468     mat->structure_only = flg;
5469     break;
5470   default:
5471     break;
5472   }
5473   if (mat->ops->setoption) {
5474     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5475   }
5476   PetscFunctionReturn(0);
5477 }
5478 
5479 /*@
5480    MatGetOption - Gets a parameter option that has been set for a matrix.
5481 
5482    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5483 
5484    Input Parameters:
5485 +  mat - the matrix
5486 -  option - the option, this only responds to certain options, check the code for which ones
5487 
5488    Output Parameter:
5489 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5490 
5491     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5492 
5493    Level: intermediate
5494 
5495    Concepts: matrices^setting options
5496 
5497 .seealso:  MatOption, MatSetOption()
5498 
5499 @*/
5500 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5501 {
5502   PetscFunctionBegin;
5503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5504   PetscValidType(mat,1);
5505 
5506   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);
5507   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()");
5508 
5509   switch (op) {
5510   case MAT_NO_OFF_PROC_ENTRIES:
5511     *flg = mat->nooffprocentries;
5512     break;
5513   case MAT_NO_OFF_PROC_ZERO_ROWS:
5514     *flg = mat->nooffproczerorows;
5515     break;
5516   case MAT_SYMMETRIC:
5517     *flg = mat->symmetric;
5518     break;
5519   case MAT_HERMITIAN:
5520     *flg = mat->hermitian;
5521     break;
5522   case MAT_STRUCTURALLY_SYMMETRIC:
5523     *flg = mat->structurally_symmetric;
5524     break;
5525   case MAT_SYMMETRY_ETERNAL:
5526     *flg = mat->symmetric_eternal;
5527     break;
5528   case MAT_SPD:
5529     *flg = mat->spd;
5530     break;
5531   default:
5532     break;
5533   }
5534   PetscFunctionReturn(0);
5535 }
5536 
5537 /*@
5538    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5539    this routine retains the old nonzero structure.
5540 
5541    Logically Collective on Mat
5542 
5543    Input Parameters:
5544 .  mat - the matrix
5545 
5546    Level: intermediate
5547 
5548    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.
5549    See the Performance chapter of the users manual for information on preallocating matrices.
5550 
5551    Concepts: matrices^zeroing
5552 
5553 .seealso: MatZeroRows()
5554 @*/
5555 PetscErrorCode MatZeroEntries(Mat mat)
5556 {
5557   PetscErrorCode ierr;
5558 
5559   PetscFunctionBegin;
5560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5561   PetscValidType(mat,1);
5562   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5563   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");
5564   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5565   MatCheckPreallocated(mat,1);
5566 
5567   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5568   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5569   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5570   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5571 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5572   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5573     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5574   }
5575 #endif
5576   PetscFunctionReturn(0);
5577 }
5578 
5579 /*@C
5580    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5581    of a set of rows and columns of a matrix.
5582 
5583    Collective on Mat
5584 
5585    Input Parameters:
5586 +  mat - the matrix
5587 .  numRows - the number of rows to remove
5588 .  rows - the global row indices
5589 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5590 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5591 -  b - optional vector of right hand side, that will be adjusted by provided solution
5592 
5593    Notes:
5594    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5595 
5596    The user can set a value in the diagonal entry (or for the AIJ and
5597    row formats can optionally remove the main diagonal entry from the
5598    nonzero structure as well, by passing 0.0 as the final argument).
5599 
5600    For the parallel case, all processes that share the matrix (i.e.,
5601    those in the communicator used for matrix creation) MUST call this
5602    routine, regardless of whether any rows being zeroed are owned by
5603    them.
5604 
5605    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5606    list only rows local to itself).
5607 
5608    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5609 
5610    Level: intermediate
5611 
5612    Concepts: matrices^zeroing rows
5613 
5614 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5615           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5616 @*/
5617 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5618 {
5619   PetscErrorCode ierr;
5620 
5621   PetscFunctionBegin;
5622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5623   PetscValidType(mat,1);
5624   if (numRows) PetscValidIntPointer(rows,3);
5625   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5626   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5627   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5628   MatCheckPreallocated(mat,1);
5629 
5630   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5631   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5632   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5633 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5634   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5635     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5636   }
5637 #endif
5638   PetscFunctionReturn(0);
5639 }
5640 
5641 /*@C
5642    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5643    of a set of rows and columns of a matrix.
5644 
5645    Collective on Mat
5646 
5647    Input Parameters:
5648 +  mat - the matrix
5649 .  is - the rows to zero
5650 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5651 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5652 -  b - optional vector of right hand side, that will be adjusted by provided solution
5653 
5654    Notes:
5655    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5656 
5657    The user can set a value in the diagonal entry (or for the AIJ and
5658    row formats can optionally remove the main diagonal entry from the
5659    nonzero structure as well, by passing 0.0 as the final argument).
5660 
5661    For the parallel case, all processes that share the matrix (i.e.,
5662    those in the communicator used for matrix creation) MUST call this
5663    routine, regardless of whether any rows being zeroed are owned by
5664    them.
5665 
5666    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5667    list only rows local to itself).
5668 
5669    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5670 
5671    Level: intermediate
5672 
5673    Concepts: matrices^zeroing rows
5674 
5675 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5676           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5677 @*/
5678 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5679 {
5680   PetscErrorCode ierr;
5681   PetscInt       numRows;
5682   const PetscInt *rows;
5683 
5684   PetscFunctionBegin;
5685   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5686   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5687   PetscValidType(mat,1);
5688   PetscValidType(is,2);
5689   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5690   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5691   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5692   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5693   PetscFunctionReturn(0);
5694 }
5695 
5696 /*@C
5697    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5698    of a set of rows of a matrix.
5699 
5700    Collective on Mat
5701 
5702    Input Parameters:
5703 +  mat - the matrix
5704 .  numRows - the number of rows to remove
5705 .  rows - the global row indices
5706 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5707 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5708 -  b - optional vector of right hand side, that will be adjusted by provided solution
5709 
5710    Notes:
5711    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5712    but does not release memory.  For the dense and block diagonal
5713    formats this does not alter the nonzero structure.
5714 
5715    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5716    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5717    merely zeroed.
5718 
5719    The user can set a value in the diagonal entry (or for the AIJ and
5720    row formats can optionally remove the main diagonal entry from the
5721    nonzero structure as well, by passing 0.0 as the final argument).
5722 
5723    For the parallel case, all processes that share the matrix (i.e.,
5724    those in the communicator used for matrix creation) MUST call this
5725    routine, regardless of whether any rows being zeroed are owned by
5726    them.
5727 
5728    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5729    list only rows local to itself).
5730 
5731    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5732    owns that are to be zeroed. This saves a global synchronization in the implementation.
5733 
5734    Level: intermediate
5735 
5736    Concepts: matrices^zeroing rows
5737 
5738 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5739           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5740 @*/
5741 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5742 {
5743   PetscErrorCode ierr;
5744 
5745   PetscFunctionBegin;
5746   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5747   PetscValidType(mat,1);
5748   if (numRows) PetscValidIntPointer(rows,3);
5749   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5750   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5751   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5752   MatCheckPreallocated(mat,1);
5753 
5754   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5755   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5756   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5757 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5758   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5759     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5760   }
5761 #endif
5762   PetscFunctionReturn(0);
5763 }
5764 
5765 /*@C
5766    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5767    of a set of rows of a matrix.
5768 
5769    Collective on Mat
5770 
5771    Input Parameters:
5772 +  mat - the matrix
5773 .  is - index set of rows to remove
5774 .  diag - value put in all diagonals of eliminated rows
5775 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5776 -  b - optional vector of right hand side, that will be adjusted by provided solution
5777 
5778    Notes:
5779    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5780    but does not release memory.  For the dense and block diagonal
5781    formats this does not alter the nonzero structure.
5782 
5783    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5784    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5785    merely zeroed.
5786 
5787    The user can set a value in the diagonal entry (or for the AIJ and
5788    row formats can optionally remove the main diagonal entry from the
5789    nonzero structure as well, by passing 0.0 as the final argument).
5790 
5791    For the parallel case, all processes that share the matrix (i.e.,
5792    those in the communicator used for matrix creation) MUST call this
5793    routine, regardless of whether any rows being zeroed are owned by
5794    them.
5795 
5796    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5797    list only rows local to itself).
5798 
5799    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5800    owns that are to be zeroed. This saves a global synchronization in the implementation.
5801 
5802    Level: intermediate
5803 
5804    Concepts: matrices^zeroing rows
5805 
5806 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5807           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5808 @*/
5809 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5810 {
5811   PetscInt       numRows;
5812   const PetscInt *rows;
5813   PetscErrorCode ierr;
5814 
5815   PetscFunctionBegin;
5816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5817   PetscValidType(mat,1);
5818   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5819   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5820   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5821   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5822   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5823   PetscFunctionReturn(0);
5824 }
5825 
5826 /*@C
5827    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5828    of a set of rows of a matrix. These rows must be local to the process.
5829 
5830    Collective on Mat
5831 
5832    Input Parameters:
5833 +  mat - the matrix
5834 .  numRows - the number of rows to remove
5835 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5836 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5837 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5838 -  b - optional vector of right hand side, that will be adjusted by provided solution
5839 
5840    Notes:
5841    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5842    but does not release memory.  For the dense and block diagonal
5843    formats this does not alter the nonzero structure.
5844 
5845    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5846    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5847    merely zeroed.
5848 
5849    The user can set a value in the diagonal entry (or for the AIJ and
5850    row formats can optionally remove the main diagonal entry from the
5851    nonzero structure as well, by passing 0.0 as the final argument).
5852 
5853    For the parallel case, all processes that share the matrix (i.e.,
5854    those in the communicator used for matrix creation) MUST call this
5855    routine, regardless of whether any rows being zeroed are owned by
5856    them.
5857 
5858    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5859    list only rows local to itself).
5860 
5861    The grid coordinates are across the entire grid, not just the local portion
5862 
5863    In Fortran idxm and idxn should be declared as
5864 $     MatStencil idxm(4,m)
5865    and the values inserted using
5866 $    idxm(MatStencil_i,1) = i
5867 $    idxm(MatStencil_j,1) = j
5868 $    idxm(MatStencil_k,1) = k
5869 $    idxm(MatStencil_c,1) = c
5870    etc
5871 
5872    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5873    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5874    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5875    DM_BOUNDARY_PERIODIC boundary type.
5876 
5877    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
5878    a single value per point) you can skip filling those indices.
5879 
5880    Level: intermediate
5881 
5882    Concepts: matrices^zeroing rows
5883 
5884 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5885           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5886 @*/
5887 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5888 {
5889   PetscInt       dim     = mat->stencil.dim;
5890   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5891   PetscInt       *dims   = mat->stencil.dims+1;
5892   PetscInt       *starts = mat->stencil.starts;
5893   PetscInt       *dxm    = (PetscInt*) rows;
5894   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5895   PetscErrorCode ierr;
5896 
5897   PetscFunctionBegin;
5898   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5899   PetscValidType(mat,1);
5900   if (numRows) PetscValidIntPointer(rows,3);
5901 
5902   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5903   for (i = 0; i < numRows; ++i) {
5904     /* Skip unused dimensions (they are ordered k, j, i, c) */
5905     for (j = 0; j < 3-sdim; ++j) dxm++;
5906     /* Local index in X dir */
5907     tmp = *dxm++ - starts[0];
5908     /* Loop over remaining dimensions */
5909     for (j = 0; j < dim-1; ++j) {
5910       /* If nonlocal, set index to be negative */
5911       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5912       /* Update local index */
5913       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5914     }
5915     /* Skip component slot if necessary */
5916     if (mat->stencil.noc) dxm++;
5917     /* Local row number */
5918     if (tmp >= 0) {
5919       jdxm[numNewRows++] = tmp;
5920     }
5921   }
5922   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5923   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5924   PetscFunctionReturn(0);
5925 }
5926 
5927 /*@C
5928    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5929    of a set of rows and columns of a matrix.
5930 
5931    Collective on Mat
5932 
5933    Input Parameters:
5934 +  mat - the matrix
5935 .  numRows - the number of rows/columns to remove
5936 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5937 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5938 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5939 -  b - optional vector of right hand side, that will be adjusted by provided solution
5940 
5941    Notes:
5942    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5943    but does not release memory.  For the dense and block diagonal
5944    formats this does not alter the nonzero structure.
5945 
5946    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5947    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5948    merely zeroed.
5949 
5950    The user can set a value in the diagonal entry (or for the AIJ and
5951    row formats can optionally remove the main diagonal entry from the
5952    nonzero structure as well, by passing 0.0 as the final argument).
5953 
5954    For the parallel case, all processes that share the matrix (i.e.,
5955    those in the communicator used for matrix creation) MUST call this
5956    routine, regardless of whether any rows being zeroed are owned by
5957    them.
5958 
5959    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5960    list only rows local to itself, but the row/column numbers are given in local numbering).
5961 
5962    The grid coordinates are across the entire grid, not just the local portion
5963 
5964    In Fortran idxm and idxn should be declared as
5965 $     MatStencil idxm(4,m)
5966    and the values inserted using
5967 $    idxm(MatStencil_i,1) = i
5968 $    idxm(MatStencil_j,1) = j
5969 $    idxm(MatStencil_k,1) = k
5970 $    idxm(MatStencil_c,1) = c
5971    etc
5972 
5973    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5974    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5975    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5976    DM_BOUNDARY_PERIODIC boundary type.
5977 
5978    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
5979    a single value per point) you can skip filling those indices.
5980 
5981    Level: intermediate
5982 
5983    Concepts: matrices^zeroing rows
5984 
5985 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5986           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5987 @*/
5988 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5989 {
5990   PetscInt       dim     = mat->stencil.dim;
5991   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5992   PetscInt       *dims   = mat->stencil.dims+1;
5993   PetscInt       *starts = mat->stencil.starts;
5994   PetscInt       *dxm    = (PetscInt*) rows;
5995   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5996   PetscErrorCode ierr;
5997 
5998   PetscFunctionBegin;
5999   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6000   PetscValidType(mat,1);
6001   if (numRows) PetscValidIntPointer(rows,3);
6002 
6003   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6004   for (i = 0; i < numRows; ++i) {
6005     /* Skip unused dimensions (they are ordered k, j, i, c) */
6006     for (j = 0; j < 3-sdim; ++j) dxm++;
6007     /* Local index in X dir */
6008     tmp = *dxm++ - starts[0];
6009     /* Loop over remaining dimensions */
6010     for (j = 0; j < dim-1; ++j) {
6011       /* If nonlocal, set index to be negative */
6012       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6013       /* Update local index */
6014       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6015     }
6016     /* Skip component slot if necessary */
6017     if (mat->stencil.noc) dxm++;
6018     /* Local row number */
6019     if (tmp >= 0) {
6020       jdxm[numNewRows++] = tmp;
6021     }
6022   }
6023   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6024   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6025   PetscFunctionReturn(0);
6026 }
6027 
6028 /*@C
6029    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6030    of a set of rows of a matrix; using local numbering of rows.
6031 
6032    Collective on Mat
6033 
6034    Input Parameters:
6035 +  mat - the matrix
6036 .  numRows - the number of rows to remove
6037 .  rows - the global row indices
6038 .  diag - value put in all diagonals of eliminated rows
6039 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6040 -  b - optional vector of right hand side, that will be adjusted by provided solution
6041 
6042    Notes:
6043    Before calling MatZeroRowsLocal(), the user must first set the
6044    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6045 
6046    For the AIJ matrix formats this removes the old nonzero structure,
6047    but does not release memory.  For the dense and block diagonal
6048    formats this does not alter the nonzero structure.
6049 
6050    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6051    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6052    merely zeroed.
6053 
6054    The user can set a value in the diagonal entry (or for the AIJ and
6055    row formats can optionally remove the main diagonal entry from the
6056    nonzero structure as well, by passing 0.0 as the final argument).
6057 
6058    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6059    owns that are to be zeroed. This saves a global synchronization in the implementation.
6060 
6061    Level: intermediate
6062 
6063    Concepts: matrices^zeroing
6064 
6065 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6066           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6067 @*/
6068 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6069 {
6070   PetscErrorCode ierr;
6071 
6072   PetscFunctionBegin;
6073   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6074   PetscValidType(mat,1);
6075   if (numRows) PetscValidIntPointer(rows,3);
6076   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6077   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6078   MatCheckPreallocated(mat,1);
6079 
6080   if (mat->ops->zerorowslocal) {
6081     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6082   } else {
6083     IS             is, newis;
6084     const PetscInt *newRows;
6085 
6086     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6087     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6088     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6089     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6090     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6091     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6092     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6093     ierr = ISDestroy(&is);CHKERRQ(ierr);
6094   }
6095   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6096 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6097   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6098     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6099   }
6100 #endif
6101   PetscFunctionReturn(0);
6102 }
6103 
6104 /*@C
6105    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6106    of a set of rows of a matrix; using local numbering of rows.
6107 
6108    Collective on Mat
6109 
6110    Input Parameters:
6111 +  mat - the matrix
6112 .  is - index set of rows to remove
6113 .  diag - value put in all diagonals of eliminated rows
6114 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6115 -  b - optional vector of right hand side, that will be adjusted by provided solution
6116 
6117    Notes:
6118    Before calling MatZeroRowsLocalIS(), the user must first set the
6119    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6120 
6121    For the AIJ matrix formats this removes the old nonzero structure,
6122    but does not release memory.  For the dense and block diagonal
6123    formats this does not alter the nonzero structure.
6124 
6125    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6126    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6127    merely zeroed.
6128 
6129    The user can set a value in the diagonal entry (or for the AIJ and
6130    row formats can optionally remove the main diagonal entry from the
6131    nonzero structure as well, by passing 0.0 as the final argument).
6132 
6133    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6134    owns that are to be zeroed. This saves a global synchronization in the implementation.
6135 
6136    Level: intermediate
6137 
6138    Concepts: matrices^zeroing
6139 
6140 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6141           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6142 @*/
6143 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6144 {
6145   PetscErrorCode ierr;
6146   PetscInt       numRows;
6147   const PetscInt *rows;
6148 
6149   PetscFunctionBegin;
6150   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6151   PetscValidType(mat,1);
6152   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6153   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6154   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6155   MatCheckPreallocated(mat,1);
6156 
6157   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6158   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6159   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6160   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6161   PetscFunctionReturn(0);
6162 }
6163 
6164 /*@C
6165    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6166    of a set of rows and columns of a matrix; using local numbering of rows.
6167 
6168    Collective on Mat
6169 
6170    Input Parameters:
6171 +  mat - the matrix
6172 .  numRows - the number of rows to remove
6173 .  rows - the global row indices
6174 .  diag - value put in all diagonals of eliminated rows
6175 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6176 -  b - optional vector of right hand side, that will be adjusted by provided solution
6177 
6178    Notes:
6179    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6180    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6181 
6182    The user can set a value in the diagonal entry (or for the AIJ and
6183    row formats can optionally remove the main diagonal entry from the
6184    nonzero structure as well, by passing 0.0 as the final argument).
6185 
6186    Level: intermediate
6187 
6188    Concepts: matrices^zeroing
6189 
6190 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6191           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6192 @*/
6193 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6194 {
6195   PetscErrorCode ierr;
6196   IS             is, newis;
6197   const PetscInt *newRows;
6198 
6199   PetscFunctionBegin;
6200   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6201   PetscValidType(mat,1);
6202   if (numRows) PetscValidIntPointer(rows,3);
6203   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6204   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6205   MatCheckPreallocated(mat,1);
6206 
6207   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6208   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6209   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6210   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6211   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6212   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6213   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6214   ierr = ISDestroy(&is);CHKERRQ(ierr);
6215   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6216 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6217   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6218     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6219   }
6220 #endif
6221   PetscFunctionReturn(0);
6222 }
6223 
6224 /*@C
6225    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6226    of a set of rows and columns of a matrix; using local numbering of rows.
6227 
6228    Collective on Mat
6229 
6230    Input Parameters:
6231 +  mat - the matrix
6232 .  is - index set of rows to remove
6233 .  diag - value put in all diagonals of eliminated rows
6234 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6235 -  b - optional vector of right hand side, that will be adjusted by provided solution
6236 
6237    Notes:
6238    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6239    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6240 
6241    The user can set a value in the diagonal entry (or for the AIJ and
6242    row formats can optionally remove the main diagonal entry from the
6243    nonzero structure as well, by passing 0.0 as the final argument).
6244 
6245    Level: intermediate
6246 
6247    Concepts: matrices^zeroing
6248 
6249 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6250           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6251 @*/
6252 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6253 {
6254   PetscErrorCode ierr;
6255   PetscInt       numRows;
6256   const PetscInt *rows;
6257 
6258   PetscFunctionBegin;
6259   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6260   PetscValidType(mat,1);
6261   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6262   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6263   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6264   MatCheckPreallocated(mat,1);
6265 
6266   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6267   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6268   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6269   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6270   PetscFunctionReturn(0);
6271 }
6272 
6273 /*@C
6274    MatGetSize - Returns the numbers of rows and columns in a matrix.
6275 
6276    Not Collective
6277 
6278    Input Parameter:
6279 .  mat - the matrix
6280 
6281    Output Parameters:
6282 +  m - the number of global rows
6283 -  n - the number of global columns
6284 
6285    Note: both output parameters can be NULL on input.
6286 
6287    Level: beginner
6288 
6289    Concepts: matrices^size
6290 
6291 .seealso: MatGetLocalSize()
6292 @*/
6293 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6294 {
6295   PetscFunctionBegin;
6296   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6297   if (m) *m = mat->rmap->N;
6298   if (n) *n = mat->cmap->N;
6299   PetscFunctionReturn(0);
6300 }
6301 
6302 /*@C
6303    MatGetLocalSize - Returns the number of rows and columns in a matrix
6304    stored locally.  This information may be implementation dependent, so
6305    use with care.
6306 
6307    Not Collective
6308 
6309    Input Parameters:
6310 .  mat - the matrix
6311 
6312    Output Parameters:
6313 +  m - the number of local rows
6314 -  n - the number of local columns
6315 
6316    Note: both output parameters can be NULL on input.
6317 
6318    Level: beginner
6319 
6320    Concepts: matrices^local size
6321 
6322 .seealso: MatGetSize()
6323 @*/
6324 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6325 {
6326   PetscFunctionBegin;
6327   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6328   if (m) PetscValidIntPointer(m,2);
6329   if (n) PetscValidIntPointer(n,3);
6330   if (m) *m = mat->rmap->n;
6331   if (n) *n = mat->cmap->n;
6332   PetscFunctionReturn(0);
6333 }
6334 
6335 /*@C
6336    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6337    this processor. (The columns of the "diagonal block")
6338 
6339    Not Collective, unless matrix has not been allocated, then collective on Mat
6340 
6341    Input Parameters:
6342 .  mat - the matrix
6343 
6344    Output Parameters:
6345 +  m - the global index of the first local column
6346 -  n - one more than the global index of the last local column
6347 
6348    Notes: both output parameters can be NULL on input.
6349 
6350    Level: developer
6351 
6352    Concepts: matrices^column ownership
6353 
6354 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6355 
6356 @*/
6357 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6358 {
6359   PetscFunctionBegin;
6360   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6361   PetscValidType(mat,1);
6362   if (m) PetscValidIntPointer(m,2);
6363   if (n) PetscValidIntPointer(n,3);
6364   MatCheckPreallocated(mat,1);
6365   if (m) *m = mat->cmap->rstart;
6366   if (n) *n = mat->cmap->rend;
6367   PetscFunctionReturn(0);
6368 }
6369 
6370 /*@C
6371    MatGetOwnershipRange - Returns the range of matrix rows owned by
6372    this processor, assuming that the matrix is laid out with the first
6373    n1 rows on the first processor, the next n2 rows on the second, etc.
6374    For certain parallel layouts this range may not be well defined.
6375 
6376    Not Collective
6377 
6378    Input Parameters:
6379 .  mat - the matrix
6380 
6381    Output Parameters:
6382 +  m - the global index of the first local row
6383 -  n - one more than the global index of the last local row
6384 
6385    Note: Both output parameters can be NULL on input.
6386 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6387 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6388 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6389 
6390    Level: beginner
6391 
6392    Concepts: matrices^row ownership
6393 
6394 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6395 
6396 @*/
6397 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6398 {
6399   PetscFunctionBegin;
6400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6401   PetscValidType(mat,1);
6402   if (m) PetscValidIntPointer(m,2);
6403   if (n) PetscValidIntPointer(n,3);
6404   MatCheckPreallocated(mat,1);
6405   if (m) *m = mat->rmap->rstart;
6406   if (n) *n = mat->rmap->rend;
6407   PetscFunctionReturn(0);
6408 }
6409 
6410 /*@C
6411    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6412    each process
6413 
6414    Not Collective, unless matrix has not been allocated, then collective on Mat
6415 
6416    Input Parameters:
6417 .  mat - the matrix
6418 
6419    Output Parameters:
6420 .  ranges - start of each processors portion plus one more than the total length at the end
6421 
6422    Level: beginner
6423 
6424    Concepts: matrices^row ownership
6425 
6426 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6427 
6428 @*/
6429 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6430 {
6431   PetscErrorCode ierr;
6432 
6433   PetscFunctionBegin;
6434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6435   PetscValidType(mat,1);
6436   MatCheckPreallocated(mat,1);
6437   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6438   PetscFunctionReturn(0);
6439 }
6440 
6441 /*@C
6442    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6443    this processor. (The columns of the "diagonal blocks" for each process)
6444 
6445    Not Collective, unless matrix has not been allocated, then collective on Mat
6446 
6447    Input Parameters:
6448 .  mat - the matrix
6449 
6450    Output Parameters:
6451 .  ranges - start of each processors portion plus one more then the total length at the end
6452 
6453    Level: beginner
6454 
6455    Concepts: matrices^column ownership
6456 
6457 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6458 
6459 @*/
6460 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6461 {
6462   PetscErrorCode ierr;
6463 
6464   PetscFunctionBegin;
6465   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6466   PetscValidType(mat,1);
6467   MatCheckPreallocated(mat,1);
6468   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6469   PetscFunctionReturn(0);
6470 }
6471 
6472 /*@C
6473    MatGetOwnershipIS - Get row and column ownership as index sets
6474 
6475    Not Collective
6476 
6477    Input Arguments:
6478 .  A - matrix of type Elemental
6479 
6480    Output Arguments:
6481 +  rows - rows in which this process owns elements
6482 .  cols - columns in which this process owns elements
6483 
6484    Level: intermediate
6485 
6486 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6487 @*/
6488 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6489 {
6490   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6491 
6492   PetscFunctionBegin;
6493   MatCheckPreallocated(A,1);
6494   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6495   if (f) {
6496     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6497   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6498     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6499     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6500   }
6501   PetscFunctionReturn(0);
6502 }
6503 
6504 /*@C
6505    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6506    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6507    to complete the factorization.
6508 
6509    Collective on Mat
6510 
6511    Input Parameters:
6512 +  mat - the matrix
6513 .  row - row permutation
6514 .  column - column permutation
6515 -  info - structure containing
6516 $      levels - number of levels of fill.
6517 $      expected fill - as ratio of original fill.
6518 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6519                 missing diagonal entries)
6520 
6521    Output Parameters:
6522 .  fact - new matrix that has been symbolically factored
6523 
6524    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6525 
6526    Most users should employ the simplified KSP interface for linear solvers
6527    instead of working directly with matrix algebra routines such as this.
6528    See, e.g., KSPCreate().
6529 
6530    Level: developer
6531 
6532   Concepts: matrices^symbolic LU factorization
6533   Concepts: matrices^factorization
6534   Concepts: LU^symbolic factorization
6535 
6536 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6537           MatGetOrdering(), MatFactorInfo
6538 
6539     Developer Note: fortran interface is not autogenerated as the f90
6540     interface defintion cannot be generated correctly [due to MatFactorInfo]
6541 
6542 @*/
6543 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6544 {
6545   PetscErrorCode ierr;
6546 
6547   PetscFunctionBegin;
6548   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6549   PetscValidType(mat,1);
6550   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6551   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6552   PetscValidPointer(info,4);
6553   PetscValidPointer(fact,5);
6554   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6555   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6556   if (!(fact)->ops->ilufactorsymbolic) {
6557     MatSolverType spackage;
6558     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6559     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6560   }
6561   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6562   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6563   MatCheckPreallocated(mat,2);
6564 
6565   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6566   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6567   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6568   PetscFunctionReturn(0);
6569 }
6570 
6571 /*@C
6572    MatICCFactorSymbolic - Performs symbolic incomplete
6573    Cholesky factorization for a symmetric matrix.  Use
6574    MatCholeskyFactorNumeric() to complete the factorization.
6575 
6576    Collective on Mat
6577 
6578    Input Parameters:
6579 +  mat - the matrix
6580 .  perm - row and column permutation
6581 -  info - structure containing
6582 $      levels - number of levels of fill.
6583 $      expected fill - as ratio of original fill.
6584 
6585    Output Parameter:
6586 .  fact - the factored matrix
6587 
6588    Notes:
6589    Most users should employ the KSP interface for linear solvers
6590    instead of working directly with matrix algebra routines such as this.
6591    See, e.g., KSPCreate().
6592 
6593    Level: developer
6594 
6595   Concepts: matrices^symbolic incomplete Cholesky factorization
6596   Concepts: matrices^factorization
6597   Concepts: Cholsky^symbolic factorization
6598 
6599 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6600 
6601     Developer Note: fortran interface is not autogenerated as the f90
6602     interface defintion cannot be generated correctly [due to MatFactorInfo]
6603 
6604 @*/
6605 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6606 {
6607   PetscErrorCode ierr;
6608 
6609   PetscFunctionBegin;
6610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6611   PetscValidType(mat,1);
6612   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6613   PetscValidPointer(info,3);
6614   PetscValidPointer(fact,4);
6615   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6616   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6617   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6618   if (!(fact)->ops->iccfactorsymbolic) {
6619     MatSolverType spackage;
6620     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6621     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6622   }
6623   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6624   MatCheckPreallocated(mat,2);
6625 
6626   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6627   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6628   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6629   PetscFunctionReturn(0);
6630 }
6631 
6632 /*@C
6633    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6634    points to an array of valid matrices, they may be reused to store the new
6635    submatrices.
6636 
6637    Collective on Mat
6638 
6639    Input Parameters:
6640 +  mat - the matrix
6641 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6642 .  irow, icol - index sets of rows and columns to extract
6643 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6644 
6645    Output Parameter:
6646 .  submat - the array of submatrices
6647 
6648    Notes:
6649    MatCreateSubMatrices() can extract ONLY sequential submatrices
6650    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6651    to extract a parallel submatrix.
6652 
6653    Some matrix types place restrictions on the row and column
6654    indices, such as that they be sorted or that they be equal to each other.
6655 
6656    The index sets may not have duplicate entries.
6657 
6658    When extracting submatrices from a parallel matrix, each processor can
6659    form a different submatrix by setting the rows and columns of its
6660    individual index sets according to the local submatrix desired.
6661 
6662    When finished using the submatrices, the user should destroy
6663    them with MatDestroySubMatrices().
6664 
6665    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6666    original matrix has not changed from that last call to MatCreateSubMatrices().
6667 
6668    This routine creates the matrices in submat; you should NOT create them before
6669    calling it. It also allocates the array of matrix pointers submat.
6670 
6671    For BAIJ matrices the index sets must respect the block structure, that is if they
6672    request one row/column in a block, they must request all rows/columns that are in
6673    that block. For example, if the block size is 2 you cannot request just row 0 and
6674    column 0.
6675 
6676    Fortran Note:
6677    The Fortran interface is slightly different from that given below; it
6678    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6679 
6680    Level: advanced
6681 
6682    Concepts: matrices^accessing submatrices
6683    Concepts: submatrices
6684 
6685 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6686 @*/
6687 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6688 {
6689   PetscErrorCode ierr;
6690   PetscInt       i;
6691   PetscBool      eq;
6692 
6693   PetscFunctionBegin;
6694   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6695   PetscValidType(mat,1);
6696   if (n) {
6697     PetscValidPointer(irow,3);
6698     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6699     PetscValidPointer(icol,4);
6700     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6701   }
6702   PetscValidPointer(submat,6);
6703   if (n && scall == MAT_REUSE_MATRIX) {
6704     PetscValidPointer(*submat,6);
6705     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6706   }
6707   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6708   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6709   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6710   MatCheckPreallocated(mat,1);
6711 
6712   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6713   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6714   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6715   for (i=0; i<n; i++) {
6716     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6717     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6718       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6719       if (eq) {
6720         if (mat->symmetric) {
6721           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6722         } else if (mat->hermitian) {
6723           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6724         } else if (mat->structurally_symmetric) {
6725           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6726         }
6727       }
6728     }
6729   }
6730   PetscFunctionReturn(0);
6731 }
6732 
6733 /*@C
6734    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6735 
6736    Collective on Mat
6737 
6738    Input Parameters:
6739 +  mat - the matrix
6740 .  n   - the number of submatrixes to be extracted
6741 .  irow, icol - index sets of rows and columns to extract
6742 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6743 
6744    Output Parameter:
6745 .  submat - the array of submatrices
6746 
6747    Level: advanced
6748 
6749    Concepts: matrices^accessing submatrices
6750    Concepts: submatrices
6751 
6752 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6753 @*/
6754 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6755 {
6756   PetscErrorCode ierr;
6757   PetscInt       i;
6758   PetscBool      eq;
6759 
6760   PetscFunctionBegin;
6761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6762   PetscValidType(mat,1);
6763   if (n) {
6764     PetscValidPointer(irow,3);
6765     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6766     PetscValidPointer(icol,4);
6767     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6768   }
6769   PetscValidPointer(submat,6);
6770   if (n && scall == MAT_REUSE_MATRIX) {
6771     PetscValidPointer(*submat,6);
6772     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6773   }
6774   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6775   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6776   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6777   MatCheckPreallocated(mat,1);
6778 
6779   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6780   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6781   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6782   for (i=0; i<n; i++) {
6783     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6784       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6785       if (eq) {
6786         if (mat->symmetric) {
6787           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6788         } else if (mat->hermitian) {
6789           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6790         } else if (mat->structurally_symmetric) {
6791           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6792         }
6793       }
6794     }
6795   }
6796   PetscFunctionReturn(0);
6797 }
6798 
6799 /*@C
6800    MatDestroyMatrices - Destroys an array of matrices.
6801 
6802    Collective on Mat
6803 
6804    Input Parameters:
6805 +  n - the number of local matrices
6806 -  mat - the matrices (note that this is a pointer to the array of matrices)
6807 
6808    Level: advanced
6809 
6810     Notes: Frees not only the matrices, but also the array that contains the matrices
6811            In Fortran will not free the array.
6812 
6813 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6814 @*/
6815 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6816 {
6817   PetscErrorCode ierr;
6818   PetscInt       i;
6819 
6820   PetscFunctionBegin;
6821   if (!*mat) PetscFunctionReturn(0);
6822   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6823   PetscValidPointer(mat,2);
6824 
6825   for (i=0; i<n; i++) {
6826     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6827   }
6828 
6829   /* memory is allocated even if n = 0 */
6830   ierr = PetscFree(*mat);CHKERRQ(ierr);
6831   PetscFunctionReturn(0);
6832 }
6833 
6834 /*@C
6835    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6836 
6837    Collective on Mat
6838 
6839    Input Parameters:
6840 +  n - the number of local matrices
6841 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6842                        sequence of MatCreateSubMatrices())
6843 
6844    Level: advanced
6845 
6846     Notes: Frees not only the matrices, but also the array that contains the matrices
6847            In Fortran will not free the array.
6848 
6849 .seealso: MatCreateSubMatrices()
6850 @*/
6851 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6852 {
6853   PetscErrorCode ierr;
6854   Mat            mat0;
6855 
6856   PetscFunctionBegin;
6857   if (!*mat) PetscFunctionReturn(0);
6858   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6859   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6860   PetscValidPointer(mat,2);
6861 
6862   mat0 = (*mat)[0];
6863   if (mat0 && mat0->ops->destroysubmatrices) {
6864     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6865   } else {
6866     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6867   }
6868   PetscFunctionReturn(0);
6869 }
6870 
6871 /*@C
6872    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6873 
6874    Collective on Mat
6875 
6876    Input Parameters:
6877 .  mat - the matrix
6878 
6879    Output Parameter:
6880 .  matstruct - the sequential matrix with the nonzero structure of mat
6881 
6882   Level: intermediate
6883 
6884 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6885 @*/
6886 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6887 {
6888   PetscErrorCode ierr;
6889 
6890   PetscFunctionBegin;
6891   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6892   PetscValidPointer(matstruct,2);
6893 
6894   PetscValidType(mat,1);
6895   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6896   MatCheckPreallocated(mat,1);
6897 
6898   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6899   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6900   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6901   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6902   PetscFunctionReturn(0);
6903 }
6904 
6905 /*@C
6906    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6907 
6908    Collective on Mat
6909 
6910    Input Parameters:
6911 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6912                        sequence of MatGetSequentialNonzeroStructure())
6913 
6914    Level: advanced
6915 
6916     Notes: Frees not only the matrices, but also the array that contains the matrices
6917 
6918 .seealso: MatGetSeqNonzeroStructure()
6919 @*/
6920 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6921 {
6922   PetscErrorCode ierr;
6923 
6924   PetscFunctionBegin;
6925   PetscValidPointer(mat,1);
6926   ierr = MatDestroy(mat);CHKERRQ(ierr);
6927   PetscFunctionReturn(0);
6928 }
6929 
6930 /*@
6931    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6932    replaces the index sets by larger ones that represent submatrices with
6933    additional overlap.
6934 
6935    Collective on Mat
6936 
6937    Input Parameters:
6938 +  mat - the matrix
6939 .  n   - the number of index sets
6940 .  is  - the array of index sets (these index sets will changed during the call)
6941 -  ov  - the additional overlap requested
6942 
6943    Options Database:
6944 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6945 
6946    Level: developer
6947 
6948    Concepts: overlap
6949    Concepts: ASM^computing overlap
6950 
6951 .seealso: MatCreateSubMatrices()
6952 @*/
6953 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6954 {
6955   PetscErrorCode ierr;
6956 
6957   PetscFunctionBegin;
6958   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6959   PetscValidType(mat,1);
6960   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6961   if (n) {
6962     PetscValidPointer(is,3);
6963     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6964   }
6965   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6966   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6967   MatCheckPreallocated(mat,1);
6968 
6969   if (!ov) PetscFunctionReturn(0);
6970   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6971   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6972   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6973   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6974   PetscFunctionReturn(0);
6975 }
6976 
6977 
6978 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6979 
6980 /*@
6981    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6982    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6983    additional overlap.
6984 
6985    Collective on Mat
6986 
6987    Input Parameters:
6988 +  mat - the matrix
6989 .  n   - the number of index sets
6990 .  is  - the array of index sets (these index sets will changed during the call)
6991 -  ov  - the additional overlap requested
6992 
6993    Options Database:
6994 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6995 
6996    Level: developer
6997 
6998    Concepts: overlap
6999    Concepts: ASM^computing overlap
7000 
7001 .seealso: MatCreateSubMatrices()
7002 @*/
7003 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7004 {
7005   PetscInt       i;
7006   PetscErrorCode ierr;
7007 
7008   PetscFunctionBegin;
7009   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7010   PetscValidType(mat,1);
7011   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7012   if (n) {
7013     PetscValidPointer(is,3);
7014     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7015   }
7016   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7017   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7018   MatCheckPreallocated(mat,1);
7019   if (!ov) PetscFunctionReturn(0);
7020   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7021   for(i=0; i<n; i++){
7022 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7023   }
7024   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7025   PetscFunctionReturn(0);
7026 }
7027 
7028 
7029 
7030 
7031 /*@
7032    MatGetBlockSize - Returns the matrix block size.
7033 
7034    Not Collective
7035 
7036    Input Parameter:
7037 .  mat - the matrix
7038 
7039    Output Parameter:
7040 .  bs - block size
7041 
7042    Notes:
7043     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7044 
7045    If the block size has not been set yet this routine returns 1.
7046 
7047    Level: intermediate
7048 
7049    Concepts: matrices^block size
7050 
7051 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7052 @*/
7053 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7054 {
7055   PetscFunctionBegin;
7056   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7057   PetscValidIntPointer(bs,2);
7058   *bs = PetscAbs(mat->rmap->bs);
7059   PetscFunctionReturn(0);
7060 }
7061 
7062 /*@
7063    MatGetBlockSizes - Returns the matrix block row and column sizes.
7064 
7065    Not Collective
7066 
7067    Input Parameter:
7068 .  mat - the matrix
7069 
7070    Output Parameter:
7071 .  rbs - row block size
7072 .  cbs - column block size
7073 
7074    Notes:
7075     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7076     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7077 
7078    If a block size has not been set yet this routine returns 1.
7079 
7080    Level: intermediate
7081 
7082    Concepts: matrices^block size
7083 
7084 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7085 @*/
7086 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7087 {
7088   PetscFunctionBegin;
7089   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7090   if (rbs) PetscValidIntPointer(rbs,2);
7091   if (cbs) PetscValidIntPointer(cbs,3);
7092   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7093   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7094   PetscFunctionReturn(0);
7095 }
7096 
7097 /*@
7098    MatSetBlockSize - Sets the matrix block size.
7099 
7100    Logically Collective on Mat
7101 
7102    Input Parameters:
7103 +  mat - the matrix
7104 -  bs - block size
7105 
7106    Notes:
7107     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7108     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7109 
7110     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7111     is compatible with the matrix local sizes.
7112 
7113    Level: intermediate
7114 
7115    Concepts: matrices^block size
7116 
7117 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7118 @*/
7119 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7120 {
7121   PetscErrorCode ierr;
7122 
7123   PetscFunctionBegin;
7124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7125   PetscValidLogicalCollectiveInt(mat,bs,2);
7126   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7127   PetscFunctionReturn(0);
7128 }
7129 
7130 /*@
7131    MatSetBlockSizes - Sets the matrix block row and column sizes.
7132 
7133    Logically Collective on Mat
7134 
7135    Input Parameters:
7136 +  mat - the matrix
7137 -  rbs - row block size
7138 -  cbs - column block size
7139 
7140    Notes:
7141     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7142     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7143     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7144 
7145     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7146     are compatible with the matrix local sizes.
7147 
7148     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7149 
7150    Level: intermediate
7151 
7152    Concepts: matrices^block size
7153 
7154 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7155 @*/
7156 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7157 {
7158   PetscErrorCode ierr;
7159 
7160   PetscFunctionBegin;
7161   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7162   PetscValidLogicalCollectiveInt(mat,rbs,2);
7163   PetscValidLogicalCollectiveInt(mat,cbs,3);
7164   if (mat->ops->setblocksizes) {
7165     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7166   }
7167   if (mat->rmap->refcnt) {
7168     ISLocalToGlobalMapping l2g = NULL;
7169     PetscLayout            nmap = NULL;
7170 
7171     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7172     if (mat->rmap->mapping) {
7173       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7174     }
7175     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7176     mat->rmap = nmap;
7177     mat->rmap->mapping = l2g;
7178   }
7179   if (mat->cmap->refcnt) {
7180     ISLocalToGlobalMapping l2g = NULL;
7181     PetscLayout            nmap = NULL;
7182 
7183     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7184     if (mat->cmap->mapping) {
7185       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7186     }
7187     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7188     mat->cmap = nmap;
7189     mat->cmap->mapping = l2g;
7190   }
7191   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7192   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7193   PetscFunctionReturn(0);
7194 }
7195 
7196 /*@
7197    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7198 
7199    Logically Collective on Mat
7200 
7201    Input Parameters:
7202 +  mat - the matrix
7203 .  fromRow - matrix from which to copy row block size
7204 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7205 
7206    Level: developer
7207 
7208    Concepts: matrices^block size
7209 
7210 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7211 @*/
7212 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7213 {
7214   PetscErrorCode ierr;
7215 
7216   PetscFunctionBegin;
7217   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7218   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7219   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7220   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7221   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7222   PetscFunctionReturn(0);
7223 }
7224 
7225 /*@
7226    MatResidual - Default routine to calculate the residual.
7227 
7228    Collective on Mat and Vec
7229 
7230    Input Parameters:
7231 +  mat - the matrix
7232 .  b   - the right-hand-side
7233 -  x   - the approximate solution
7234 
7235    Output Parameter:
7236 .  r - location to store the residual
7237 
7238    Level: developer
7239 
7240 .keywords: MG, default, multigrid, residual
7241 
7242 .seealso: PCMGSetResidual()
7243 @*/
7244 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7245 {
7246   PetscErrorCode ierr;
7247 
7248   PetscFunctionBegin;
7249   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7250   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7251   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7252   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7253   PetscValidType(mat,1);
7254   MatCheckPreallocated(mat,1);
7255   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7256   if (!mat->ops->residual) {
7257     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7258     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7259   } else {
7260     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7261   }
7262   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7263   PetscFunctionReturn(0);
7264 }
7265 
7266 /*@C
7267     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7268 
7269    Collective on Mat
7270 
7271     Input Parameters:
7272 +   mat - the matrix
7273 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7274 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7275 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7276                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7277                  always used.
7278 
7279     Output Parameters:
7280 +   n - number of rows in the (possibly compressed) matrix
7281 .   ia - the row pointers [of length n+1]
7282 .   ja - the column indices
7283 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7284            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7285 
7286     Level: developer
7287 
7288     Notes:
7289     You CANNOT change any of the ia[] or ja[] values.
7290 
7291     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7292 
7293     Fortran Notes:
7294     In Fortran use
7295 $
7296 $      PetscInt ia(1), ja(1)
7297 $      PetscOffset iia, jja
7298 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7299 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7300 
7301      or
7302 $
7303 $    PetscInt, pointer :: ia(:),ja(:)
7304 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7305 $    ! Access the ith and jth entries via ia(i) and ja(j)
7306 
7307 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7308 @*/
7309 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7310 {
7311   PetscErrorCode ierr;
7312 
7313   PetscFunctionBegin;
7314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7315   PetscValidType(mat,1);
7316   PetscValidIntPointer(n,5);
7317   if (ia) PetscValidIntPointer(ia,6);
7318   if (ja) PetscValidIntPointer(ja,7);
7319   PetscValidIntPointer(done,8);
7320   MatCheckPreallocated(mat,1);
7321   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7322   else {
7323     *done = PETSC_TRUE;
7324     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7325     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7326     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7327   }
7328   PetscFunctionReturn(0);
7329 }
7330 
7331 /*@C
7332     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7333 
7334     Collective on Mat
7335 
7336     Input Parameters:
7337 +   mat - the matrix
7338 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7339 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7340                 symmetrized
7341 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7342                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7343                  always used.
7344 .   n - number of columns in the (possibly compressed) matrix
7345 .   ia - the column pointers
7346 -   ja - the row indices
7347 
7348     Output Parameters:
7349 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7350 
7351     Note:
7352     This routine zeros out n, ia, and ja. This is to prevent accidental
7353     us of the array after it has been restored. If you pass NULL, it will
7354     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7355 
7356     Level: developer
7357 
7358 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7359 @*/
7360 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7361 {
7362   PetscErrorCode ierr;
7363 
7364   PetscFunctionBegin;
7365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7366   PetscValidType(mat,1);
7367   PetscValidIntPointer(n,4);
7368   if (ia) PetscValidIntPointer(ia,5);
7369   if (ja) PetscValidIntPointer(ja,6);
7370   PetscValidIntPointer(done,7);
7371   MatCheckPreallocated(mat,1);
7372   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7373   else {
7374     *done = PETSC_TRUE;
7375     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7376   }
7377   PetscFunctionReturn(0);
7378 }
7379 
7380 /*@C
7381     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7382     MatGetRowIJ().
7383 
7384     Collective on Mat
7385 
7386     Input Parameters:
7387 +   mat - the matrix
7388 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7389 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7390                 symmetrized
7391 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7392                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7393                  always used.
7394 .   n - size of (possibly compressed) matrix
7395 .   ia - the row pointers
7396 -   ja - the column indices
7397 
7398     Output Parameters:
7399 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7400 
7401     Note:
7402     This routine zeros out n, ia, and ja. This is to prevent accidental
7403     us of the array after it has been restored. If you pass NULL, it will
7404     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7405 
7406     Level: developer
7407 
7408 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7409 @*/
7410 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7411 {
7412   PetscErrorCode ierr;
7413 
7414   PetscFunctionBegin;
7415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7416   PetscValidType(mat,1);
7417   if (ia) PetscValidIntPointer(ia,6);
7418   if (ja) PetscValidIntPointer(ja,7);
7419   PetscValidIntPointer(done,8);
7420   MatCheckPreallocated(mat,1);
7421 
7422   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7423   else {
7424     *done = PETSC_TRUE;
7425     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7426     if (n)  *n = 0;
7427     if (ia) *ia = NULL;
7428     if (ja) *ja = NULL;
7429   }
7430   PetscFunctionReturn(0);
7431 }
7432 
7433 /*@C
7434     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7435     MatGetColumnIJ().
7436 
7437     Collective on Mat
7438 
7439     Input Parameters:
7440 +   mat - the matrix
7441 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7442 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7443                 symmetrized
7444 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7445                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7446                  always used.
7447 
7448     Output Parameters:
7449 +   n - size of (possibly compressed) matrix
7450 .   ia - the column pointers
7451 .   ja - the row indices
7452 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7453 
7454     Level: developer
7455 
7456 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7457 @*/
7458 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7459 {
7460   PetscErrorCode ierr;
7461 
7462   PetscFunctionBegin;
7463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7464   PetscValidType(mat,1);
7465   if (ia) PetscValidIntPointer(ia,5);
7466   if (ja) PetscValidIntPointer(ja,6);
7467   PetscValidIntPointer(done,7);
7468   MatCheckPreallocated(mat,1);
7469 
7470   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7471   else {
7472     *done = PETSC_TRUE;
7473     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7474     if (n)  *n = 0;
7475     if (ia) *ia = NULL;
7476     if (ja) *ja = NULL;
7477   }
7478   PetscFunctionReturn(0);
7479 }
7480 
7481 /*@C
7482     MatColoringPatch -Used inside matrix coloring routines that
7483     use MatGetRowIJ() and/or MatGetColumnIJ().
7484 
7485     Collective on Mat
7486 
7487     Input Parameters:
7488 +   mat - the matrix
7489 .   ncolors - max color value
7490 .   n   - number of entries in colorarray
7491 -   colorarray - array indicating color for each column
7492 
7493     Output Parameters:
7494 .   iscoloring - coloring generated using colorarray information
7495 
7496     Level: developer
7497 
7498 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7499 
7500 @*/
7501 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7502 {
7503   PetscErrorCode ierr;
7504 
7505   PetscFunctionBegin;
7506   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7507   PetscValidType(mat,1);
7508   PetscValidIntPointer(colorarray,4);
7509   PetscValidPointer(iscoloring,5);
7510   MatCheckPreallocated(mat,1);
7511 
7512   if (!mat->ops->coloringpatch) {
7513     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7514   } else {
7515     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7516   }
7517   PetscFunctionReturn(0);
7518 }
7519 
7520 
7521 /*@
7522    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7523 
7524    Logically Collective on Mat
7525 
7526    Input Parameter:
7527 .  mat - the factored matrix to be reset
7528 
7529    Notes:
7530    This routine should be used only with factored matrices formed by in-place
7531    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7532    format).  This option can save memory, for example, when solving nonlinear
7533    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7534    ILU(0) preconditioner.
7535 
7536    Note that one can specify in-place ILU(0) factorization by calling
7537 .vb
7538      PCType(pc,PCILU);
7539      PCFactorSeUseInPlace(pc);
7540 .ve
7541    or by using the options -pc_type ilu -pc_factor_in_place
7542 
7543    In-place factorization ILU(0) can also be used as a local
7544    solver for the blocks within the block Jacobi or additive Schwarz
7545    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7546    for details on setting local solver options.
7547 
7548    Most users should employ the simplified KSP interface for linear solvers
7549    instead of working directly with matrix algebra routines such as this.
7550    See, e.g., KSPCreate().
7551 
7552    Level: developer
7553 
7554 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7555 
7556    Concepts: matrices^unfactored
7557 
7558 @*/
7559 PetscErrorCode MatSetUnfactored(Mat mat)
7560 {
7561   PetscErrorCode ierr;
7562 
7563   PetscFunctionBegin;
7564   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7565   PetscValidType(mat,1);
7566   MatCheckPreallocated(mat,1);
7567   mat->factortype = MAT_FACTOR_NONE;
7568   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7569   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7570   PetscFunctionReturn(0);
7571 }
7572 
7573 /*MC
7574     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7575 
7576     Synopsis:
7577     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7578 
7579     Not collective
7580 
7581     Input Parameter:
7582 .   x - matrix
7583 
7584     Output Parameters:
7585 +   xx_v - the Fortran90 pointer to the array
7586 -   ierr - error code
7587 
7588     Example of Usage:
7589 .vb
7590       PetscScalar, pointer xx_v(:,:)
7591       ....
7592       call MatDenseGetArrayF90(x,xx_v,ierr)
7593       a = xx_v(3)
7594       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7595 .ve
7596 
7597     Level: advanced
7598 
7599 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7600 
7601     Concepts: matrices^accessing array
7602 
7603 M*/
7604 
7605 /*MC
7606     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7607     accessed with MatDenseGetArrayF90().
7608 
7609     Synopsis:
7610     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7611 
7612     Not collective
7613 
7614     Input Parameters:
7615 +   x - matrix
7616 -   xx_v - the Fortran90 pointer to the array
7617 
7618     Output Parameter:
7619 .   ierr - error code
7620 
7621     Example of Usage:
7622 .vb
7623        PetscScalar, pointer xx_v(:,:)
7624        ....
7625        call MatDenseGetArrayF90(x,xx_v,ierr)
7626        a = xx_v(3)
7627        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7628 .ve
7629 
7630     Level: advanced
7631 
7632 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7633 
7634 M*/
7635 
7636 
7637 /*MC
7638     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7639 
7640     Synopsis:
7641     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7642 
7643     Not collective
7644 
7645     Input Parameter:
7646 .   x - matrix
7647 
7648     Output Parameters:
7649 +   xx_v - the Fortran90 pointer to the array
7650 -   ierr - error code
7651 
7652     Example of Usage:
7653 .vb
7654       PetscScalar, pointer xx_v(:)
7655       ....
7656       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7657       a = xx_v(3)
7658       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7659 .ve
7660 
7661     Level: advanced
7662 
7663 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7664 
7665     Concepts: matrices^accessing array
7666 
7667 M*/
7668 
7669 /*MC
7670     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7671     accessed with MatSeqAIJGetArrayF90().
7672 
7673     Synopsis:
7674     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7675 
7676     Not collective
7677 
7678     Input Parameters:
7679 +   x - matrix
7680 -   xx_v - the Fortran90 pointer to the array
7681 
7682     Output Parameter:
7683 .   ierr - error code
7684 
7685     Example of Usage:
7686 .vb
7687        PetscScalar, pointer xx_v(:)
7688        ....
7689        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7690        a = xx_v(3)
7691        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7692 .ve
7693 
7694     Level: advanced
7695 
7696 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7697 
7698 M*/
7699 
7700 
7701 /*@
7702     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7703                       as the original matrix.
7704 
7705     Collective on Mat
7706 
7707     Input Parameters:
7708 +   mat - the original matrix
7709 .   isrow - parallel IS containing the rows this processor should obtain
7710 .   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.
7711 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7712 
7713     Output Parameter:
7714 .   newmat - the new submatrix, of the same type as the old
7715 
7716     Level: advanced
7717 
7718     Notes:
7719     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7720 
7721     Some matrix types place restrictions on the row and column indices, such
7722     as that they be sorted or that they be equal to each other.
7723 
7724     The index sets may not have duplicate entries.
7725 
7726       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7727    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7728    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7729    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7730    you are finished using it.
7731 
7732     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7733     the input matrix.
7734 
7735     If iscol is NULL then all columns are obtained (not supported in Fortran).
7736 
7737    Example usage:
7738    Consider the following 8x8 matrix with 34 non-zero values, that is
7739    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7740    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7741    as follows:
7742 
7743 .vb
7744             1  2  0  |  0  3  0  |  0  4
7745     Proc0   0  5  6  |  7  0  0  |  8  0
7746             9  0 10  | 11  0  0  | 12  0
7747     -------------------------------------
7748            13  0 14  | 15 16 17  |  0  0
7749     Proc1   0 18  0  | 19 20 21  |  0  0
7750             0  0  0  | 22 23  0  | 24  0
7751     -------------------------------------
7752     Proc2  25 26 27  |  0  0 28  | 29  0
7753            30  0  0  | 31 32 33  |  0 34
7754 .ve
7755 
7756     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7757 
7758 .vb
7759             2  0  |  0  3  0  |  0
7760     Proc0   5  6  |  7  0  0  |  8
7761     -------------------------------
7762     Proc1  18  0  | 19 20 21  |  0
7763     -------------------------------
7764     Proc2  26 27  |  0  0 28  | 29
7765             0  0  | 31 32 33  |  0
7766 .ve
7767 
7768 
7769     Concepts: matrices^submatrices
7770 
7771 .seealso: MatCreateSubMatrices()
7772 @*/
7773 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7774 {
7775   PetscErrorCode ierr;
7776   PetscMPIInt    size;
7777   Mat            *local;
7778   IS             iscoltmp;
7779 
7780   PetscFunctionBegin;
7781   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7782   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7783   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7784   PetscValidPointer(newmat,5);
7785   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7786   PetscValidType(mat,1);
7787   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7788   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7789 
7790   MatCheckPreallocated(mat,1);
7791   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7792 
7793   if (!iscol || isrow == iscol) {
7794     PetscBool   stride;
7795     PetscMPIInt grabentirematrix = 0,grab;
7796     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7797     if (stride) {
7798       PetscInt first,step,n,rstart,rend;
7799       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7800       if (step == 1) {
7801         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7802         if (rstart == first) {
7803           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7804           if (n == rend-rstart) {
7805             grabentirematrix = 1;
7806           }
7807         }
7808       }
7809     }
7810     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7811     if (grab) {
7812       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7813       if (cll == MAT_INITIAL_MATRIX) {
7814         *newmat = mat;
7815         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7816       }
7817       PetscFunctionReturn(0);
7818     }
7819   }
7820 
7821   if (!iscol) {
7822     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7823   } else {
7824     iscoltmp = iscol;
7825   }
7826 
7827   /* if original matrix is on just one processor then use submatrix generated */
7828   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7829     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7830     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7831     PetscFunctionReturn(0);
7832   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7833     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7834     *newmat = *local;
7835     ierr    = PetscFree(local);CHKERRQ(ierr);
7836     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7837     PetscFunctionReturn(0);
7838   } else if (!mat->ops->createsubmatrix) {
7839     /* Create a new matrix type that implements the operation using the full matrix */
7840     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7841     switch (cll) {
7842     case MAT_INITIAL_MATRIX:
7843       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7844       break;
7845     case MAT_REUSE_MATRIX:
7846       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7847       break;
7848     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7849     }
7850     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7851     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7852     PetscFunctionReturn(0);
7853   }
7854 
7855   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7856   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7857   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7858   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7859 
7860   /* Propagate symmetry information for diagonal blocks */
7861   if (isrow == iscoltmp) {
7862     if (mat->symmetric_set && mat->symmetric) {
7863       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7864     }
7865     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
7866       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7867     }
7868     if (mat->hermitian_set && mat->hermitian) {
7869       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7870     }
7871     if (mat->spd_set && mat->spd) {
7872       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
7873     }
7874   }
7875 
7876   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7877   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7878   PetscFunctionReturn(0);
7879 }
7880 
7881 /*@
7882    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7883    used during the assembly process to store values that belong to
7884    other processors.
7885 
7886    Not Collective
7887 
7888    Input Parameters:
7889 +  mat   - the matrix
7890 .  size  - the initial size of the stash.
7891 -  bsize - the initial size of the block-stash(if used).
7892 
7893    Options Database Keys:
7894 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7895 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7896 
7897    Level: intermediate
7898 
7899    Notes:
7900      The block-stash is used for values set with MatSetValuesBlocked() while
7901      the stash is used for values set with MatSetValues()
7902 
7903      Run with the option -info and look for output of the form
7904      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7905      to determine the appropriate value, MM, to use for size and
7906      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7907      to determine the value, BMM to use for bsize
7908 
7909    Concepts: stash^setting matrix size
7910    Concepts: matrices^stash
7911 
7912 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7913 
7914 @*/
7915 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7916 {
7917   PetscErrorCode ierr;
7918 
7919   PetscFunctionBegin;
7920   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7921   PetscValidType(mat,1);
7922   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7923   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7924   PetscFunctionReturn(0);
7925 }
7926 
7927 /*@
7928    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7929      the matrix
7930 
7931    Neighbor-wise Collective on Mat
7932 
7933    Input Parameters:
7934 +  mat   - the matrix
7935 .  x,y - the vectors
7936 -  w - where the result is stored
7937 
7938    Level: intermediate
7939 
7940    Notes:
7941     w may be the same vector as y.
7942 
7943     This allows one to use either the restriction or interpolation (its transpose)
7944     matrix to do the interpolation
7945 
7946     Concepts: interpolation
7947 
7948 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7949 
7950 @*/
7951 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7952 {
7953   PetscErrorCode ierr;
7954   PetscInt       M,N,Ny;
7955 
7956   PetscFunctionBegin;
7957   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7958   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7959   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7960   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7961   PetscValidType(A,1);
7962   MatCheckPreallocated(A,1);
7963   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7964   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7965   if (M == Ny) {
7966     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7967   } else {
7968     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7969   }
7970   PetscFunctionReturn(0);
7971 }
7972 
7973 /*@
7974    MatInterpolate - y = A*x or A'*x depending on the shape of
7975      the matrix
7976 
7977    Neighbor-wise Collective on Mat
7978 
7979    Input Parameters:
7980 +  mat   - the matrix
7981 -  x,y - the vectors
7982 
7983    Level: intermediate
7984 
7985    Notes:
7986     This allows one to use either the restriction or interpolation (its transpose)
7987     matrix to do the interpolation
7988 
7989    Concepts: matrices^interpolation
7990 
7991 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7992 
7993 @*/
7994 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7995 {
7996   PetscErrorCode ierr;
7997   PetscInt       M,N,Ny;
7998 
7999   PetscFunctionBegin;
8000   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8001   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8002   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8003   PetscValidType(A,1);
8004   MatCheckPreallocated(A,1);
8005   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8006   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8007   if (M == Ny) {
8008     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8009   } else {
8010     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8011   }
8012   PetscFunctionReturn(0);
8013 }
8014 
8015 /*@
8016    MatRestrict - y = A*x or A'*x
8017 
8018    Neighbor-wise Collective on Mat
8019 
8020    Input Parameters:
8021 +  mat   - the matrix
8022 -  x,y - the vectors
8023 
8024    Level: intermediate
8025 
8026    Notes:
8027     This allows one to use either the restriction or interpolation (its transpose)
8028     matrix to do the restriction
8029 
8030    Concepts: matrices^restriction
8031 
8032 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8033 
8034 @*/
8035 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8036 {
8037   PetscErrorCode ierr;
8038   PetscInt       M,N,Ny;
8039 
8040   PetscFunctionBegin;
8041   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8042   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8043   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8044   PetscValidType(A,1);
8045   MatCheckPreallocated(A,1);
8046 
8047   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8048   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8049   if (M == Ny) {
8050     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8051   } else {
8052     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8053   }
8054   PetscFunctionReturn(0);
8055 }
8056 
8057 /*@C
8058    MatGetNullSpace - retrieves the null space of a matrix.
8059 
8060    Logically Collective on Mat and MatNullSpace
8061 
8062    Input Parameters:
8063 +  mat - the matrix
8064 -  nullsp - the null space object
8065 
8066    Level: developer
8067 
8068    Concepts: null space^attaching to matrix
8069 
8070 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8071 @*/
8072 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8073 {
8074   PetscFunctionBegin;
8075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8076   PetscValidPointer(nullsp,2);
8077   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8078   PetscFunctionReturn(0);
8079 }
8080 
8081 /*@C
8082    MatSetNullSpace - attaches a null space to a matrix.
8083 
8084    Logically Collective on Mat and MatNullSpace
8085 
8086    Input Parameters:
8087 +  mat - the matrix
8088 -  nullsp - the null space object
8089 
8090    Level: advanced
8091 
8092    Notes:
8093       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8094 
8095       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8096       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8097 
8098       You can remove the null space by calling this routine with an nullsp of NULL
8099 
8100 
8101       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8102    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).
8103    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
8104    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
8105    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).
8106 
8107       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8108 
8109     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
8110     routine also automatically calls MatSetTransposeNullSpace().
8111 
8112    Concepts: null space^attaching to matrix
8113 
8114 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8115 @*/
8116 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8117 {
8118   PetscErrorCode ierr;
8119 
8120   PetscFunctionBegin;
8121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8122   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8123   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8124   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8125   mat->nullsp = nullsp;
8126   if (mat->symmetric_set && mat->symmetric) {
8127     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8128   }
8129   PetscFunctionReturn(0);
8130 }
8131 
8132 /*@
8133    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8134 
8135    Logically Collective on Mat and MatNullSpace
8136 
8137    Input Parameters:
8138 +  mat - the matrix
8139 -  nullsp - the null space object
8140 
8141    Level: developer
8142 
8143    Concepts: null space^attaching to matrix
8144 
8145 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8146 @*/
8147 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8148 {
8149   PetscFunctionBegin;
8150   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8151   PetscValidType(mat,1);
8152   PetscValidPointer(nullsp,2);
8153   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8154   PetscFunctionReturn(0);
8155 }
8156 
8157 /*@
8158    MatSetTransposeNullSpace - attaches a null space to a matrix.
8159 
8160    Logically Collective on Mat and MatNullSpace
8161 
8162    Input Parameters:
8163 +  mat - the matrix
8164 -  nullsp - the null space object
8165 
8166    Level: advanced
8167 
8168    Notes:
8169       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.
8170       You must also call MatSetNullSpace()
8171 
8172 
8173       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8174    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).
8175    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
8176    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
8177    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).
8178 
8179       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8180 
8181    Concepts: null space^attaching to matrix
8182 
8183 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8184 @*/
8185 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8186 {
8187   PetscErrorCode ierr;
8188 
8189   PetscFunctionBegin;
8190   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8191   PetscValidType(mat,1);
8192   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8193   MatCheckPreallocated(mat,1);
8194   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8195   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8196   mat->transnullsp = nullsp;
8197   PetscFunctionReturn(0);
8198 }
8199 
8200 /*@
8201    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8202         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8203 
8204    Logically Collective on Mat and MatNullSpace
8205 
8206    Input Parameters:
8207 +  mat - the matrix
8208 -  nullsp - the null space object
8209 
8210    Level: advanced
8211 
8212    Notes:
8213       Overwrites any previous near null space that may have been attached
8214 
8215       You can remove the null space by calling this routine with an nullsp of NULL
8216 
8217    Concepts: null space^attaching to matrix
8218 
8219 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8220 @*/
8221 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8222 {
8223   PetscErrorCode ierr;
8224 
8225   PetscFunctionBegin;
8226   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8227   PetscValidType(mat,1);
8228   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8229   MatCheckPreallocated(mat,1);
8230   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8231   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8232   mat->nearnullsp = nullsp;
8233   PetscFunctionReturn(0);
8234 }
8235 
8236 /*@
8237    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8238 
8239    Not Collective
8240 
8241    Input Parameters:
8242 .  mat - the matrix
8243 
8244    Output Parameters:
8245 .  nullsp - the null space object, NULL if not set
8246 
8247    Level: developer
8248 
8249    Concepts: null space^attaching to matrix
8250 
8251 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8252 @*/
8253 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8254 {
8255   PetscFunctionBegin;
8256   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8257   PetscValidType(mat,1);
8258   PetscValidPointer(nullsp,2);
8259   MatCheckPreallocated(mat,1);
8260   *nullsp = mat->nearnullsp;
8261   PetscFunctionReturn(0);
8262 }
8263 
8264 /*@C
8265    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8266 
8267    Collective on Mat
8268 
8269    Input Parameters:
8270 +  mat - the matrix
8271 .  row - row/column permutation
8272 .  fill - expected fill factor >= 1.0
8273 -  level - level of fill, for ICC(k)
8274 
8275    Notes:
8276    Probably really in-place only when level of fill is zero, otherwise allocates
8277    new space to store factored matrix and deletes previous memory.
8278 
8279    Most users should employ the simplified KSP interface for linear solvers
8280    instead of working directly with matrix algebra routines such as this.
8281    See, e.g., KSPCreate().
8282 
8283    Level: developer
8284 
8285    Concepts: matrices^incomplete Cholesky factorization
8286    Concepts: Cholesky factorization
8287 
8288 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8289 
8290     Developer Note: fortran interface is not autogenerated as the f90
8291     interface defintion cannot be generated correctly [due to MatFactorInfo]
8292 
8293 @*/
8294 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8295 {
8296   PetscErrorCode ierr;
8297 
8298   PetscFunctionBegin;
8299   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8300   PetscValidType(mat,1);
8301   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8302   PetscValidPointer(info,3);
8303   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8304   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8305   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8306   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8307   MatCheckPreallocated(mat,1);
8308   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8309   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8310   PetscFunctionReturn(0);
8311 }
8312 
8313 /*@
8314    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8315          ghosted ones.
8316 
8317    Not Collective
8318 
8319    Input Parameters:
8320 +  mat - the matrix
8321 -  diag = the diagonal values, including ghost ones
8322 
8323    Level: developer
8324 
8325    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8326 
8327 .seealso: MatDiagonalScale()
8328 @*/
8329 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8330 {
8331   PetscErrorCode ierr;
8332   PetscMPIInt    size;
8333 
8334   PetscFunctionBegin;
8335   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8336   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8337   PetscValidType(mat,1);
8338 
8339   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8340   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8341   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8342   if (size == 1) {
8343     PetscInt n,m;
8344     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8345     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8346     if (m == n) {
8347       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8348     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8349   } else {
8350     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8351   }
8352   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8353   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8354   PetscFunctionReturn(0);
8355 }
8356 
8357 /*@
8358    MatGetInertia - Gets the inertia from a factored matrix
8359 
8360    Collective on Mat
8361 
8362    Input Parameter:
8363 .  mat - the matrix
8364 
8365    Output Parameters:
8366 +   nneg - number of negative eigenvalues
8367 .   nzero - number of zero eigenvalues
8368 -   npos - number of positive eigenvalues
8369 
8370    Level: advanced
8371 
8372    Notes: Matrix must have been factored by MatCholeskyFactor()
8373 
8374 
8375 @*/
8376 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8377 {
8378   PetscErrorCode ierr;
8379 
8380   PetscFunctionBegin;
8381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8382   PetscValidType(mat,1);
8383   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8385   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8386   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8387   PetscFunctionReturn(0);
8388 }
8389 
8390 /* ----------------------------------------------------------------*/
8391 /*@C
8392    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8393 
8394    Neighbor-wise Collective on Mat and Vecs
8395 
8396    Input Parameters:
8397 +  mat - the factored matrix
8398 -  b - the right-hand-side vectors
8399 
8400    Output Parameter:
8401 .  x - the result vectors
8402 
8403    Notes:
8404    The vectors b and x cannot be the same.  I.e., one cannot
8405    call MatSolves(A,x,x).
8406 
8407    Notes:
8408    Most users should employ the simplified KSP interface for linear solvers
8409    instead of working directly with matrix algebra routines such as this.
8410    See, e.g., KSPCreate().
8411 
8412    Level: developer
8413 
8414    Concepts: matrices^triangular solves
8415 
8416 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8417 @*/
8418 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8419 {
8420   PetscErrorCode ierr;
8421 
8422   PetscFunctionBegin;
8423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8424   PetscValidType(mat,1);
8425   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8426   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8427   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8428 
8429   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8430   MatCheckPreallocated(mat,1);
8431   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8432   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8433   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8434   PetscFunctionReturn(0);
8435 }
8436 
8437 /*@
8438    MatIsSymmetric - Test whether a matrix is symmetric
8439 
8440    Collective on Mat
8441 
8442    Input Parameter:
8443 +  A - the matrix to test
8444 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8445 
8446    Output Parameters:
8447 .  flg - the result
8448 
8449    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8450 
8451    Level: intermediate
8452 
8453    Concepts: matrix^symmetry
8454 
8455 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8456 @*/
8457 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8458 {
8459   PetscErrorCode ierr;
8460 
8461   PetscFunctionBegin;
8462   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8463   PetscValidPointer(flg,2);
8464 
8465   if (!A->symmetric_set) {
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     if (!tol) {
8473       A->symmetric_set = PETSC_TRUE;
8474       A->symmetric     = *flg;
8475       if (A->symmetric) {
8476         A->structurally_symmetric_set = PETSC_TRUE;
8477         A->structurally_symmetric     = PETSC_TRUE;
8478       }
8479     }
8480   } else if (A->symmetric) {
8481     *flg = PETSC_TRUE;
8482   } else if (!tol) {
8483     *flg = PETSC_FALSE;
8484   } else {
8485     if (!A->ops->issymmetric) {
8486       MatType mattype;
8487       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8488       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8489     }
8490     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8491   }
8492   PetscFunctionReturn(0);
8493 }
8494 
8495 /*@
8496    MatIsHermitian - Test whether a matrix is Hermitian
8497 
8498    Collective on Mat
8499 
8500    Input Parameter:
8501 +  A - the matrix to test
8502 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8503 
8504    Output Parameters:
8505 .  flg - the result
8506 
8507    Level: intermediate
8508 
8509    Concepts: matrix^symmetry
8510 
8511 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8512           MatIsSymmetricKnown(), MatIsSymmetric()
8513 @*/
8514 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8515 {
8516   PetscErrorCode ierr;
8517 
8518   PetscFunctionBegin;
8519   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8520   PetscValidPointer(flg,2);
8521 
8522   if (!A->hermitian_set) {
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     if (!tol) {
8530       A->hermitian_set = PETSC_TRUE;
8531       A->hermitian     = *flg;
8532       if (A->hermitian) {
8533         A->structurally_symmetric_set = PETSC_TRUE;
8534         A->structurally_symmetric     = PETSC_TRUE;
8535       }
8536     }
8537   } else if (A->hermitian) {
8538     *flg = PETSC_TRUE;
8539   } else if (!tol) {
8540     *flg = PETSC_FALSE;
8541   } else {
8542     if (!A->ops->ishermitian) {
8543       MatType mattype;
8544       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8545       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8546     }
8547     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8548   }
8549   PetscFunctionReturn(0);
8550 }
8551 
8552 /*@
8553    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8554 
8555    Not Collective
8556 
8557    Input Parameter:
8558 .  A - the matrix to check
8559 
8560    Output Parameters:
8561 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8562 -  flg - the result
8563 
8564    Level: advanced
8565 
8566    Concepts: matrix^symmetry
8567 
8568    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8569          if you want it explicitly checked
8570 
8571 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8572 @*/
8573 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8574 {
8575   PetscFunctionBegin;
8576   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8577   PetscValidPointer(set,2);
8578   PetscValidPointer(flg,3);
8579   if (A->symmetric_set) {
8580     *set = PETSC_TRUE;
8581     *flg = A->symmetric;
8582   } else {
8583     *set = PETSC_FALSE;
8584   }
8585   PetscFunctionReturn(0);
8586 }
8587 
8588 /*@
8589    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8590 
8591    Not Collective
8592 
8593    Input Parameter:
8594 .  A - the matrix to check
8595 
8596    Output Parameters:
8597 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8598 -  flg - the result
8599 
8600    Level: advanced
8601 
8602    Concepts: matrix^symmetry
8603 
8604    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8605          if you want it explicitly checked
8606 
8607 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8608 @*/
8609 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8610 {
8611   PetscFunctionBegin;
8612   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8613   PetscValidPointer(set,2);
8614   PetscValidPointer(flg,3);
8615   if (A->hermitian_set) {
8616     *set = PETSC_TRUE;
8617     *flg = A->hermitian;
8618   } else {
8619     *set = PETSC_FALSE;
8620   }
8621   PetscFunctionReturn(0);
8622 }
8623 
8624 /*@
8625    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8626 
8627    Collective on Mat
8628 
8629    Input Parameter:
8630 .  A - the matrix to test
8631 
8632    Output Parameters:
8633 .  flg - the result
8634 
8635    Level: intermediate
8636 
8637    Concepts: matrix^symmetry
8638 
8639 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8640 @*/
8641 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8642 {
8643   PetscErrorCode ierr;
8644 
8645   PetscFunctionBegin;
8646   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8647   PetscValidPointer(flg,2);
8648   if (!A->structurally_symmetric_set) {
8649     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8650     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8651 
8652     A->structurally_symmetric_set = PETSC_TRUE;
8653   }
8654   *flg = A->structurally_symmetric;
8655   PetscFunctionReturn(0);
8656 }
8657 
8658 /*@
8659    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8660        to be communicated to other processors during the MatAssemblyBegin/End() process
8661 
8662     Not collective
8663 
8664    Input Parameter:
8665 .   vec - the vector
8666 
8667    Output Parameters:
8668 +   nstash   - the size of the stash
8669 .   reallocs - the number of additional mallocs incurred.
8670 .   bnstash   - the size of the block stash
8671 -   breallocs - the number of additional mallocs incurred.in the block stash
8672 
8673    Level: advanced
8674 
8675 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8676 
8677 @*/
8678 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8679 {
8680   PetscErrorCode ierr;
8681 
8682   PetscFunctionBegin;
8683   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8684   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8685   PetscFunctionReturn(0);
8686 }
8687 
8688 /*@C
8689    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8690      parallel layout
8691 
8692    Collective on Mat
8693 
8694    Input Parameter:
8695 .  mat - the matrix
8696 
8697    Output Parameter:
8698 +   right - (optional) vector that the matrix can be multiplied against
8699 -   left - (optional) vector that the matrix vector product can be stored in
8700 
8701    Notes:
8702     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().
8703 
8704   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8705 
8706   Level: advanced
8707 
8708 .seealso: MatCreate(), VecDestroy()
8709 @*/
8710 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8711 {
8712   PetscErrorCode ierr;
8713 
8714   PetscFunctionBegin;
8715   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8716   PetscValidType(mat,1);
8717   if (mat->ops->getvecs) {
8718     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8719   } else {
8720     PetscInt rbs,cbs;
8721     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8722     if (right) {
8723       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8724       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8725       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8726       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8727       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8728       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8729     }
8730     if (left) {
8731       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8732       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8733       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8734       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8735       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8736       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8737     }
8738   }
8739   PetscFunctionReturn(0);
8740 }
8741 
8742 /*@C
8743    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8744      with default values.
8745 
8746    Not Collective
8747 
8748    Input Parameters:
8749 .    info - the MatFactorInfo data structure
8750 
8751 
8752    Notes: The solvers are generally used through the KSP and PC objects, for example
8753           PCLU, PCILU, PCCHOLESKY, PCICC
8754 
8755    Level: developer
8756 
8757 .seealso: MatFactorInfo
8758 
8759     Developer Note: fortran interface is not autogenerated as the f90
8760     interface defintion cannot be generated correctly [due to MatFactorInfo]
8761 
8762 @*/
8763 
8764 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8765 {
8766   PetscErrorCode ierr;
8767 
8768   PetscFunctionBegin;
8769   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8770   PetscFunctionReturn(0);
8771 }
8772 
8773 /*@
8774    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8775 
8776    Collective on Mat
8777 
8778    Input Parameters:
8779 +  mat - the factored matrix
8780 -  is - the index set defining the Schur indices (0-based)
8781 
8782    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8783 
8784    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8785 
8786    Level: developer
8787 
8788    Concepts:
8789 
8790 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8791           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8792 
8793 @*/
8794 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8795 {
8796   PetscErrorCode ierr,(*f)(Mat,IS);
8797 
8798   PetscFunctionBegin;
8799   PetscValidType(mat,1);
8800   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8801   PetscValidType(is,2);
8802   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8803   PetscCheckSameComm(mat,1,is,2);
8804   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8805   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8806   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");
8807   if (mat->schur) {
8808     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8809   }
8810   ierr = (*f)(mat,is);CHKERRQ(ierr);
8811   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8812   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8813   PetscFunctionReturn(0);
8814 }
8815 
8816 /*@
8817   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8818 
8819    Logically Collective on Mat
8820 
8821    Input Parameters:
8822 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8823 .  S - location where to return the Schur complement, can be NULL
8824 -  status - the status of the Schur complement matrix, can be NULL
8825 
8826    Notes:
8827    You must call MatFactorSetSchurIS() before calling this routine.
8828 
8829    The routine provides a copy of the Schur matrix stored within the solver data structures.
8830    The caller must destroy the object when it is no longer needed.
8831    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8832 
8833    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)
8834 
8835    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
8836    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8837 
8838    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8839 
8840    Level: advanced
8841 
8842    References:
8843 
8844 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8845 @*/
8846 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8847 {
8848   PetscErrorCode ierr;
8849 
8850   PetscFunctionBegin;
8851   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8852   if (S) PetscValidPointer(S,2);
8853   if (status) PetscValidPointer(status,3);
8854   if (S) {
8855     PetscErrorCode (*f)(Mat,Mat*);
8856 
8857     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8858     if (f) {
8859       ierr = (*f)(F,S);CHKERRQ(ierr);
8860     } else {
8861       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8862     }
8863   }
8864   if (status) *status = F->schur_status;
8865   PetscFunctionReturn(0);
8866 }
8867 
8868 /*@
8869   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8870 
8871    Logically Collective on Mat
8872 
8873    Input Parameters:
8874 +  F - the factored matrix obtained by calling MatGetFactor()
8875 .  *S - location where to return the Schur complement, can be NULL
8876 -  status - the status of the Schur complement matrix, can be NULL
8877 
8878    Notes:
8879    You must call MatFactorSetSchurIS() before calling this routine.
8880 
8881    Schur complement mode is currently implemented for sequential matrices.
8882    The routine returns a the Schur Complement stored within the data strutures of the solver.
8883    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8884    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8885 
8886    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8887 
8888    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8889 
8890    Level: advanced
8891 
8892    References:
8893 
8894 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8895 @*/
8896 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8897 {
8898   PetscFunctionBegin;
8899   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8900   if (S) PetscValidPointer(S,2);
8901   if (status) PetscValidPointer(status,3);
8902   if (S) *S = F->schur;
8903   if (status) *status = F->schur_status;
8904   PetscFunctionReturn(0);
8905 }
8906 
8907 /*@
8908   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8909 
8910    Logically Collective on Mat
8911 
8912    Input Parameters:
8913 +  F - the factored matrix obtained by calling MatGetFactor()
8914 .  *S - location where the Schur complement is stored
8915 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8916 
8917    Notes:
8918 
8919    Level: advanced
8920 
8921    References:
8922 
8923 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8924 @*/
8925 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8926 {
8927   PetscErrorCode ierr;
8928 
8929   PetscFunctionBegin;
8930   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8931   if (S) {
8932     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8933     *S = NULL;
8934   }
8935   F->schur_status = status;
8936   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8937   PetscFunctionReturn(0);
8938 }
8939 
8940 /*@
8941   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8942 
8943    Logically Collective on Mat
8944 
8945    Input Parameters:
8946 +  F - the factored matrix obtained by calling MatGetFactor()
8947 .  rhs - location where the right hand side of the Schur complement system is stored
8948 -  sol - location where the solution of the Schur complement system has to be returned
8949 
8950    Notes:
8951    The sizes of the vectors should match the size of the Schur complement
8952 
8953    Must be called after MatFactorSetSchurIS()
8954 
8955    Level: advanced
8956 
8957    References:
8958 
8959 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8960 @*/
8961 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8962 {
8963   PetscErrorCode ierr;
8964 
8965   PetscFunctionBegin;
8966   PetscValidType(F,1);
8967   PetscValidType(rhs,2);
8968   PetscValidType(sol,3);
8969   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8970   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8971   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8972   PetscCheckSameComm(F,1,rhs,2);
8973   PetscCheckSameComm(F,1,sol,3);
8974   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8975   switch (F->schur_status) {
8976   case MAT_FACTOR_SCHUR_FACTORED:
8977     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8978     break;
8979   case MAT_FACTOR_SCHUR_INVERTED:
8980     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8981     break;
8982   default:
8983     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8984     break;
8985   }
8986   PetscFunctionReturn(0);
8987 }
8988 
8989 /*@
8990   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8991 
8992    Logically Collective on Mat
8993 
8994    Input Parameters:
8995 +  F - the factored matrix obtained by calling MatGetFactor()
8996 .  rhs - location where the right hand side of the Schur complement system is stored
8997 -  sol - location where the solution of the Schur complement system has to be returned
8998 
8999    Notes:
9000    The sizes of the vectors should match the size of the Schur complement
9001 
9002    Must be called after MatFactorSetSchurIS()
9003 
9004    Level: advanced
9005 
9006    References:
9007 
9008 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9009 @*/
9010 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9011 {
9012   PetscErrorCode ierr;
9013 
9014   PetscFunctionBegin;
9015   PetscValidType(F,1);
9016   PetscValidType(rhs,2);
9017   PetscValidType(sol,3);
9018   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9019   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9020   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9021   PetscCheckSameComm(F,1,rhs,2);
9022   PetscCheckSameComm(F,1,sol,3);
9023   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9024   switch (F->schur_status) {
9025   case MAT_FACTOR_SCHUR_FACTORED:
9026     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9027     break;
9028   case MAT_FACTOR_SCHUR_INVERTED:
9029     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9030     break;
9031   default:
9032     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9033     break;
9034   }
9035   PetscFunctionReturn(0);
9036 }
9037 
9038 /*@
9039   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9040 
9041    Logically Collective on Mat
9042 
9043    Input Parameters:
9044 +  F - the factored matrix obtained by calling MatGetFactor()
9045 
9046    Notes: Must be called after MatFactorSetSchurIS().
9047 
9048    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9049 
9050    Level: advanced
9051 
9052    References:
9053 
9054 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9055 @*/
9056 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9057 {
9058   PetscErrorCode ierr;
9059 
9060   PetscFunctionBegin;
9061   PetscValidType(F,1);
9062   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9063   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9064   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9065   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9066   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9067   PetscFunctionReturn(0);
9068 }
9069 
9070 /*@
9071   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9072 
9073    Logically Collective on Mat
9074 
9075    Input Parameters:
9076 +  F - the factored matrix obtained by calling MatGetFactor()
9077 
9078    Notes: Must be called after MatFactorSetSchurIS().
9079 
9080    Level: advanced
9081 
9082    References:
9083 
9084 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9085 @*/
9086 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9087 {
9088   PetscErrorCode ierr;
9089 
9090   PetscFunctionBegin;
9091   PetscValidType(F,1);
9092   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9093   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9094   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9095   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9096   PetscFunctionReturn(0);
9097 }
9098 
9099 /*@
9100    MatPtAP - Creates the matrix product C = P^T * A * P
9101 
9102    Neighbor-wise Collective on Mat
9103 
9104    Input Parameters:
9105 +  A - the matrix
9106 .  P - the projection matrix
9107 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9108 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9109           if the result is a dense matrix this is irrelevent
9110 
9111    Output Parameters:
9112 .  C - the product matrix
9113 
9114    Notes:
9115    C will be created and must be destroyed by the user with MatDestroy().
9116 
9117    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9118    which inherit from AIJ.
9119 
9120    Level: intermediate
9121 
9122 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9123 @*/
9124 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9125 {
9126   PetscErrorCode ierr;
9127   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9128   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9129   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9130 
9131   PetscFunctionBegin;
9132   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9133   PetscValidType(A,1);
9134   MatCheckPreallocated(A,1);
9135   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9136   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9137   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9138   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9139   PetscValidType(P,2);
9140   MatCheckPreallocated(P,2);
9141   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9142   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9143 
9144   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);
9145   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);
9146   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9147   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9148 
9149   if (scall == MAT_REUSE_MATRIX) {
9150     PetscValidPointer(*C,5);
9151     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9152 
9153     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9154     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9155     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9156     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9157     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9158     PetscFunctionReturn(0);
9159   }
9160 
9161   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9162   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9163 
9164   fA = A->ops->ptap;
9165   fP = P->ops->ptap;
9166   if (fP == fA) {
9167     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9168     ptap = fA;
9169   } else {
9170     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9171     char ptapname[256];
9172     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9173     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9174     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9175     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9176     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9177     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9178     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);
9179   }
9180 
9181   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9182   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9183   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9184   PetscFunctionReturn(0);
9185 }
9186 
9187 /*@
9188    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9189 
9190    Neighbor-wise Collective on Mat
9191 
9192    Input Parameters:
9193 +  A - the matrix
9194 -  P - the projection matrix
9195 
9196    Output Parameters:
9197 .  C - the product matrix
9198 
9199    Notes:
9200    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9201    the user using MatDeatroy().
9202 
9203    This routine is currently only implemented for pairs of AIJ matrices and classes
9204    which inherit from AIJ.  C will be of type MATAIJ.
9205 
9206    Level: intermediate
9207 
9208 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9209 @*/
9210 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9211 {
9212   PetscErrorCode ierr;
9213 
9214   PetscFunctionBegin;
9215   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9216   PetscValidType(A,1);
9217   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9218   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9219   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9220   PetscValidType(P,2);
9221   MatCheckPreallocated(P,2);
9222   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9223   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9224   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9225   PetscValidType(C,3);
9226   MatCheckPreallocated(C,3);
9227   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9228   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);
9229   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);
9230   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);
9231   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);
9232   MatCheckPreallocated(A,1);
9233 
9234   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9235   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9236   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9237   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9238   PetscFunctionReturn(0);
9239 }
9240 
9241 /*@
9242    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9243 
9244    Neighbor-wise Collective on Mat
9245 
9246    Input Parameters:
9247 +  A - the matrix
9248 -  P - the projection matrix
9249 
9250    Output Parameters:
9251 .  C - the (i,j) structure of the product matrix
9252 
9253    Notes:
9254    C will be created and must be destroyed by the user with MatDestroy().
9255 
9256    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9257    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9258    this (i,j) structure by calling MatPtAPNumeric().
9259 
9260    Level: intermediate
9261 
9262 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9263 @*/
9264 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9265 {
9266   PetscErrorCode ierr;
9267 
9268   PetscFunctionBegin;
9269   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9270   PetscValidType(A,1);
9271   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9272   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9273   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9274   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9275   PetscValidType(P,2);
9276   MatCheckPreallocated(P,2);
9277   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9278   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9279   PetscValidPointer(C,3);
9280 
9281   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);
9282   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);
9283   MatCheckPreallocated(A,1);
9284 
9285   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9286   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9287   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9288   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9289 
9290   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9291   PetscFunctionReturn(0);
9292 }
9293 
9294 /*@
9295    MatRARt - Creates the matrix product C = R * A * R^T
9296 
9297    Neighbor-wise Collective on Mat
9298 
9299    Input Parameters:
9300 +  A - the matrix
9301 .  R - the projection matrix
9302 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9303 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9304           if the result is a dense matrix this is irrelevent
9305 
9306    Output Parameters:
9307 .  C - the product matrix
9308 
9309    Notes:
9310    C will be created and must be destroyed by the user with MatDestroy().
9311 
9312    This routine is currently only implemented for pairs of AIJ matrices and classes
9313    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9314    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9315    We recommend using MatPtAP().
9316 
9317    Level: intermediate
9318 
9319 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9320 @*/
9321 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9322 {
9323   PetscErrorCode ierr;
9324 
9325   PetscFunctionBegin;
9326   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9327   PetscValidType(A,1);
9328   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9329   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9330   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9331   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9332   PetscValidType(R,2);
9333   MatCheckPreallocated(R,2);
9334   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9335   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9336   PetscValidPointer(C,3);
9337   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);
9338 
9339   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9340   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9341   MatCheckPreallocated(A,1);
9342 
9343   if (!A->ops->rart) {
9344     Mat Rt;
9345     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9346     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9347     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9348     PetscFunctionReturn(0);
9349   }
9350   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9351   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9352   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9353   PetscFunctionReturn(0);
9354 }
9355 
9356 /*@
9357    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9358 
9359    Neighbor-wise Collective on Mat
9360 
9361    Input Parameters:
9362 +  A - the matrix
9363 -  R - the projection matrix
9364 
9365    Output Parameters:
9366 .  C - the product matrix
9367 
9368    Notes:
9369    C must have been created by calling MatRARtSymbolic and must be destroyed by
9370    the user using MatDestroy().
9371 
9372    This routine is currently only implemented for pairs of AIJ matrices and classes
9373    which inherit from AIJ.  C will be of type MATAIJ.
9374 
9375    Level: intermediate
9376 
9377 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9378 @*/
9379 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9380 {
9381   PetscErrorCode ierr;
9382 
9383   PetscFunctionBegin;
9384   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9385   PetscValidType(A,1);
9386   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9387   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9388   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9389   PetscValidType(R,2);
9390   MatCheckPreallocated(R,2);
9391   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9392   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9393   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9394   PetscValidType(C,3);
9395   MatCheckPreallocated(C,3);
9396   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9397   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);
9398   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);
9399   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);
9400   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);
9401   MatCheckPreallocated(A,1);
9402 
9403   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9404   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9405   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9406   PetscFunctionReturn(0);
9407 }
9408 
9409 /*@
9410    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9411 
9412    Neighbor-wise Collective on Mat
9413 
9414    Input Parameters:
9415 +  A - the matrix
9416 -  R - the projection matrix
9417 
9418    Output Parameters:
9419 .  C - the (i,j) structure of the product matrix
9420 
9421    Notes:
9422    C will be created and must be destroyed by the user with MatDestroy().
9423 
9424    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9425    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9426    this (i,j) structure by calling MatRARtNumeric().
9427 
9428    Level: intermediate
9429 
9430 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9431 @*/
9432 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9433 {
9434   PetscErrorCode ierr;
9435 
9436   PetscFunctionBegin;
9437   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9438   PetscValidType(A,1);
9439   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9440   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9441   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9442   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9443   PetscValidType(R,2);
9444   MatCheckPreallocated(R,2);
9445   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9446   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9447   PetscValidPointer(C,3);
9448 
9449   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);
9450   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);
9451   MatCheckPreallocated(A,1);
9452   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9453   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9454   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9455 
9456   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9457   PetscFunctionReturn(0);
9458 }
9459 
9460 /*@
9461    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9462 
9463    Neighbor-wise Collective on Mat
9464 
9465    Input Parameters:
9466 +  A - the left matrix
9467 .  B - the right matrix
9468 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9469 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9470           if the result is a dense matrix this is irrelevent
9471 
9472    Output Parameters:
9473 .  C - the product matrix
9474 
9475    Notes:
9476    Unless scall is MAT_REUSE_MATRIX C will be created.
9477 
9478    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
9479    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9480 
9481    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9482    actually needed.
9483 
9484    If you have many matrices with the same non-zero structure to multiply, you
9485    should either
9486 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9487 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9488    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
9489    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9490 
9491    Level: intermediate
9492 
9493 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9494 @*/
9495 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9496 {
9497   PetscErrorCode ierr;
9498   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9499   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9500   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9501 
9502   PetscFunctionBegin;
9503   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9504   PetscValidType(A,1);
9505   MatCheckPreallocated(A,1);
9506   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9507   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9508   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9509   PetscValidType(B,2);
9510   MatCheckPreallocated(B,2);
9511   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9512   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9513   PetscValidPointer(C,3);
9514   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9515   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);
9516   if (scall == MAT_REUSE_MATRIX) {
9517     PetscValidPointer(*C,5);
9518     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9519     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9520     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9521     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9522     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9523     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9524     PetscFunctionReturn(0);
9525   }
9526   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9527   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9528 
9529   fA = A->ops->matmult;
9530   fB = B->ops->matmult;
9531   if (fB == fA) {
9532     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9533     mult = fB;
9534   } else {
9535     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9536     char multname[256];
9537     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9538     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9539     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9540     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9541     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9542     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9543     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);
9544   }
9545   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9546   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9547   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9548   PetscFunctionReturn(0);
9549 }
9550 
9551 /*@
9552    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9553    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9554 
9555    Neighbor-wise Collective on Mat
9556 
9557    Input Parameters:
9558 +  A - the left matrix
9559 .  B - the right matrix
9560 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9561       if C is a dense matrix this is irrelevent
9562 
9563    Output Parameters:
9564 .  C - the product matrix
9565 
9566    Notes:
9567    Unless scall is MAT_REUSE_MATRIX C will be created.
9568 
9569    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9570    actually needed.
9571 
9572    This routine is currently implemented for
9573     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9574     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9575     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9576 
9577    Level: intermediate
9578 
9579    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9580      We should incorporate them into PETSc.
9581 
9582 .seealso: MatMatMult(), MatMatMultNumeric()
9583 @*/
9584 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9585 {
9586   PetscErrorCode ierr;
9587   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9588   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9589   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9590 
9591   PetscFunctionBegin;
9592   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9593   PetscValidType(A,1);
9594   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9595   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9596 
9597   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9598   PetscValidType(B,2);
9599   MatCheckPreallocated(B,2);
9600   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9601   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9602   PetscValidPointer(C,3);
9603 
9604   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);
9605   if (fill == PETSC_DEFAULT) fill = 2.0;
9606   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9607   MatCheckPreallocated(A,1);
9608 
9609   Asymbolic = A->ops->matmultsymbolic;
9610   Bsymbolic = B->ops->matmultsymbolic;
9611   if (Asymbolic == Bsymbolic) {
9612     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9613     symbolic = Bsymbolic;
9614   } else { /* dispatch based on the type of A and B */
9615     char symbolicname[256];
9616     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9617     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9618     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9619     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9620     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9621     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9622     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);
9623   }
9624   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9625   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9626   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9627   PetscFunctionReturn(0);
9628 }
9629 
9630 /*@
9631    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9632    Call this routine after first calling MatMatMultSymbolic().
9633 
9634    Neighbor-wise Collective on Mat
9635 
9636    Input Parameters:
9637 +  A - the left matrix
9638 -  B - the right matrix
9639 
9640    Output Parameters:
9641 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9642 
9643    Notes:
9644    C must have been created with MatMatMultSymbolic().
9645 
9646    This routine is currently implemented for
9647     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9648     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9649     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9650 
9651    Level: intermediate
9652 
9653 .seealso: MatMatMult(), MatMatMultSymbolic()
9654 @*/
9655 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9656 {
9657   PetscErrorCode ierr;
9658 
9659   PetscFunctionBegin;
9660   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9661   PetscFunctionReturn(0);
9662 }
9663 
9664 /*@
9665    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9666 
9667    Neighbor-wise Collective on Mat
9668 
9669    Input Parameters:
9670 +  A - the left matrix
9671 .  B - the right matrix
9672 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9673 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9674 
9675    Output Parameters:
9676 .  C - the product matrix
9677 
9678    Notes:
9679    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9680 
9681    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9682 
9683   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9684    actually needed.
9685 
9686    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9687 
9688    Level: intermediate
9689 
9690 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9691 @*/
9692 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9693 {
9694   PetscErrorCode ierr;
9695   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9696   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9697 
9698   PetscFunctionBegin;
9699   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9700   PetscValidType(A,1);
9701   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9702   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9703   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9704   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9705   PetscValidType(B,2);
9706   MatCheckPreallocated(B,2);
9707   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9708   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9709   PetscValidPointer(C,3);
9710   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);
9711   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9712   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9713   MatCheckPreallocated(A,1);
9714 
9715   fA = A->ops->mattransposemult;
9716   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9717   fB = B->ops->mattransposemult;
9718   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9719   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);
9720 
9721   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9722   if (scall == MAT_INITIAL_MATRIX) {
9723     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9724     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9725     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9726   }
9727   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9728   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9729   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9730   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9731   PetscFunctionReturn(0);
9732 }
9733 
9734 /*@
9735    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9736 
9737    Neighbor-wise Collective on Mat
9738 
9739    Input Parameters:
9740 +  A - the left matrix
9741 .  B - the right matrix
9742 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9743 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9744 
9745    Output Parameters:
9746 .  C - the product matrix
9747 
9748    Notes:
9749    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9750 
9751    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9752 
9753   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9754    actually needed.
9755 
9756    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9757    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9758 
9759    Level: intermediate
9760 
9761 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9762 @*/
9763 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9764 {
9765   PetscErrorCode ierr;
9766   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9767   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9768   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9769 
9770   PetscFunctionBegin;
9771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9772   PetscValidType(A,1);
9773   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9774   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9775   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9776   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9777   PetscValidType(B,2);
9778   MatCheckPreallocated(B,2);
9779   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9780   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9781   PetscValidPointer(C,3);
9782   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);
9783   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9784   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9785   MatCheckPreallocated(A,1);
9786 
9787   fA = A->ops->transposematmult;
9788   fB = B->ops->transposematmult;
9789   if (fB==fA) {
9790     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9791     transposematmult = fA;
9792   } else {
9793     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9794     char multname[256];
9795     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9796     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9797     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9798     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9799     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9800     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9801     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);
9802   }
9803   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9804   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9805   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9806   PetscFunctionReturn(0);
9807 }
9808 
9809 /*@
9810    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9811 
9812    Neighbor-wise Collective on Mat
9813 
9814    Input Parameters:
9815 +  A - the left matrix
9816 .  B - the middle matrix
9817 .  C - the right matrix
9818 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9819 -  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
9820           if the result is a dense matrix this is irrelevent
9821 
9822    Output Parameters:
9823 .  D - the product matrix
9824 
9825    Notes:
9826    Unless scall is MAT_REUSE_MATRIX D will be created.
9827 
9828    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9829 
9830    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9831    actually needed.
9832 
9833    If you have many matrices with the same non-zero structure to multiply, you
9834    should use MAT_REUSE_MATRIX in all calls but the first or
9835 
9836    Level: intermediate
9837 
9838 .seealso: MatMatMult, MatPtAP()
9839 @*/
9840 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9841 {
9842   PetscErrorCode ierr;
9843   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9844   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9845   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9846   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9847 
9848   PetscFunctionBegin;
9849   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9850   PetscValidType(A,1);
9851   MatCheckPreallocated(A,1);
9852   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9853   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9854   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9855   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9856   PetscValidType(B,2);
9857   MatCheckPreallocated(B,2);
9858   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9859   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9860   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9861   PetscValidPointer(C,3);
9862   MatCheckPreallocated(C,3);
9863   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9864   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9865   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);
9866   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);
9867   if (scall == MAT_REUSE_MATRIX) {
9868     PetscValidPointer(*D,6);
9869     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9870     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9871     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9872     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9873     PetscFunctionReturn(0);
9874   }
9875   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9876   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9877 
9878   fA = A->ops->matmatmult;
9879   fB = B->ops->matmatmult;
9880   fC = C->ops->matmatmult;
9881   if (fA == fB && fA == fC) {
9882     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9883     mult = fA;
9884   } else {
9885     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9886     char multname[256];
9887     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9888     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9889     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9890     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9891     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9892     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9893     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9894     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9895     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);
9896   }
9897   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9898   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9899   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9900   PetscFunctionReturn(0);
9901 }
9902 
9903 /*@
9904    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9905 
9906    Collective on Mat
9907 
9908    Input Parameters:
9909 +  mat - the matrix
9910 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9911 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9912 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9913 
9914    Output Parameter:
9915 .  matredundant - redundant matrix
9916 
9917    Notes:
9918    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9919    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9920 
9921    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9922    calling it.
9923 
9924    Level: advanced
9925 
9926    Concepts: subcommunicator
9927    Concepts: duplicate matrix
9928 
9929 .seealso: MatDestroy()
9930 @*/
9931 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9932 {
9933   PetscErrorCode ierr;
9934   MPI_Comm       comm;
9935   PetscMPIInt    size;
9936   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9937   Mat_Redundant  *redund=NULL;
9938   PetscSubcomm   psubcomm=NULL;
9939   MPI_Comm       subcomm_in=subcomm;
9940   Mat            *matseq;
9941   IS             isrow,iscol;
9942   PetscBool      newsubcomm=PETSC_FALSE;
9943 
9944   PetscFunctionBegin;
9945   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9946   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9947     PetscValidPointer(*matredundant,5);
9948     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9949   }
9950 
9951   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9952   if (size == 1 || nsubcomm == 1) {
9953     if (reuse == MAT_INITIAL_MATRIX) {
9954       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9955     } else {
9956       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");
9957       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9958     }
9959     PetscFunctionReturn(0);
9960   }
9961 
9962   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9963   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9964   MatCheckPreallocated(mat,1);
9965 
9966   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9967   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9968     /* create psubcomm, then get subcomm */
9969     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9970     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9971     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9972 
9973     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9974     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9975     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9976     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9977     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9978     newsubcomm = PETSC_TRUE;
9979     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9980   }
9981 
9982   /* get isrow, iscol and a local sequential matrix matseq[0] */
9983   if (reuse == MAT_INITIAL_MATRIX) {
9984     mloc_sub = PETSC_DECIDE;
9985     nloc_sub = PETSC_DECIDE;
9986     if (bs < 1) {
9987       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9988       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9989     } else {
9990       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9991       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
9992     }
9993     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9994     rstart = rend - mloc_sub;
9995     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9996     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9997   } else { /* reuse == MAT_REUSE_MATRIX */
9998     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");
9999     /* retrieve subcomm */
10000     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10001     redund = (*matredundant)->redundant;
10002     isrow  = redund->isrow;
10003     iscol  = redund->iscol;
10004     matseq = redund->matseq;
10005   }
10006   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10007 
10008   /* get matredundant over subcomm */
10009   if (reuse == MAT_INITIAL_MATRIX) {
10010     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10011 
10012     /* create a supporting struct and attach it to C for reuse */
10013     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10014     (*matredundant)->redundant = redund;
10015     redund->isrow              = isrow;
10016     redund->iscol              = iscol;
10017     redund->matseq             = matseq;
10018     if (newsubcomm) {
10019       redund->subcomm          = subcomm;
10020     } else {
10021       redund->subcomm          = MPI_COMM_NULL;
10022     }
10023   } else {
10024     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10025   }
10026   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10027   PetscFunctionReturn(0);
10028 }
10029 
10030 /*@C
10031    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10032    a given 'mat' object. Each submatrix can span multiple procs.
10033 
10034    Collective on Mat
10035 
10036    Input Parameters:
10037 +  mat - the matrix
10038 .  subcomm - the subcommunicator obtained by com_split(comm)
10039 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10040 
10041    Output Parameter:
10042 .  subMat - 'parallel submatrices each spans a given subcomm
10043 
10044   Notes:
10045   The submatrix partition across processors is dictated by 'subComm' a
10046   communicator obtained by com_split(comm). The comm_split
10047   is not restriced to be grouped with consecutive original ranks.
10048 
10049   Due the comm_split() usage, the parallel layout of the submatrices
10050   map directly to the layout of the original matrix [wrt the local
10051   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10052   into the 'DiagonalMat' of the subMat, hence it is used directly from
10053   the subMat. However the offDiagMat looses some columns - and this is
10054   reconstructed with MatSetValues()
10055 
10056   Level: advanced
10057 
10058   Concepts: subcommunicator
10059   Concepts: submatrices
10060 
10061 .seealso: MatCreateSubMatrices()
10062 @*/
10063 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10064 {
10065   PetscErrorCode ierr;
10066   PetscMPIInt    commsize,subCommSize;
10067 
10068   PetscFunctionBegin;
10069   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10070   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10071   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10072 
10073   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");
10074   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10075   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10076   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10077   PetscFunctionReturn(0);
10078 }
10079 
10080 /*@
10081    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10082 
10083    Not Collective
10084 
10085    Input Arguments:
10086    mat - matrix to extract local submatrix from
10087    isrow - local row indices for submatrix
10088    iscol - local column indices for submatrix
10089 
10090    Output Arguments:
10091    submat - the submatrix
10092 
10093    Level: intermediate
10094 
10095    Notes:
10096    The submat should be returned with MatRestoreLocalSubMatrix().
10097 
10098    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10099    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10100 
10101    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10102    MatSetValuesBlockedLocal() will also be implemented.
10103 
10104    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10105    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10106 
10107 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10108 @*/
10109 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10110 {
10111   PetscErrorCode ierr;
10112 
10113   PetscFunctionBegin;
10114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10115   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10116   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10117   PetscCheckSameComm(isrow,2,iscol,3);
10118   PetscValidPointer(submat,4);
10119   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10120 
10121   if (mat->ops->getlocalsubmatrix) {
10122     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10123   } else {
10124     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10125   }
10126   PetscFunctionReturn(0);
10127 }
10128 
10129 /*@
10130    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10131 
10132    Not Collective
10133 
10134    Input Arguments:
10135    mat - matrix to extract local submatrix from
10136    isrow - local row indices for submatrix
10137    iscol - local column indices for submatrix
10138    submat - the submatrix
10139 
10140    Level: intermediate
10141 
10142 .seealso: MatGetLocalSubMatrix()
10143 @*/
10144 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10145 {
10146   PetscErrorCode ierr;
10147 
10148   PetscFunctionBegin;
10149   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10150   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10151   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10152   PetscCheckSameComm(isrow,2,iscol,3);
10153   PetscValidPointer(submat,4);
10154   if (*submat) {
10155     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10156   }
10157 
10158   if (mat->ops->restorelocalsubmatrix) {
10159     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10160   } else {
10161     ierr = MatDestroy(submat);CHKERRQ(ierr);
10162   }
10163   *submat = NULL;
10164   PetscFunctionReturn(0);
10165 }
10166 
10167 /* --------------------------------------------------------*/
10168 /*@
10169    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10170 
10171    Collective on Mat
10172 
10173    Input Parameter:
10174 .  mat - the matrix
10175 
10176    Output Parameter:
10177 .  is - if any rows have zero diagonals this contains the list of them
10178 
10179    Level: developer
10180 
10181    Concepts: matrix-vector product
10182 
10183 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10184 @*/
10185 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10186 {
10187   PetscErrorCode ierr;
10188 
10189   PetscFunctionBegin;
10190   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10191   PetscValidType(mat,1);
10192   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10193   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10194 
10195   if (!mat->ops->findzerodiagonals) {
10196     Vec                diag;
10197     const PetscScalar *a;
10198     PetscInt          *rows;
10199     PetscInt           rStart, rEnd, r, nrow = 0;
10200 
10201     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10202     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10203     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10204     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10205     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10206     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10207     nrow = 0;
10208     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10209     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10210     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10211     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10212   } else {
10213     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10214   }
10215   PetscFunctionReturn(0);
10216 }
10217 
10218 /*@
10219    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10220 
10221    Collective on Mat
10222 
10223    Input Parameter:
10224 .  mat - the matrix
10225 
10226    Output Parameter:
10227 .  is - contains the list of rows with off block diagonal entries
10228 
10229    Level: developer
10230 
10231    Concepts: matrix-vector product
10232 
10233 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10234 @*/
10235 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10236 {
10237   PetscErrorCode ierr;
10238 
10239   PetscFunctionBegin;
10240   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10241   PetscValidType(mat,1);
10242   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10243   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10244 
10245   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10246   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10247   PetscFunctionReturn(0);
10248 }
10249 
10250 /*@C
10251   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10252 
10253   Collective on Mat
10254 
10255   Input Parameters:
10256 . mat - the matrix
10257 
10258   Output Parameters:
10259 . values - the block inverses in column major order (FORTRAN-like)
10260 
10261    Note:
10262    This routine is not available from Fortran.
10263 
10264   Level: advanced
10265 
10266 .seealso: MatInvertBockDiagonalMat
10267 @*/
10268 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10269 {
10270   PetscErrorCode ierr;
10271 
10272   PetscFunctionBegin;
10273   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10274   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10275   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10276   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10277   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10278   PetscFunctionReturn(0);
10279 }
10280 
10281 /*@
10282   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10283 
10284   Collective on Mat
10285 
10286   Input Parameters:
10287 . A - the matrix
10288 
10289   Output Parameters:
10290 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10291 
10292   Level: advanced
10293 
10294 .seealso: MatInvertBockDiagonal()
10295 @*/
10296 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10297 {
10298   PetscErrorCode     ierr;
10299   const PetscScalar *vals;
10300   PetscInt          *dnnz;
10301   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10302 
10303   PetscFunctionBegin;
10304   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10305   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10306   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10307   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10308   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10309   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10310   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10311   for(j = 0; j < m/bs; j++) {
10312     dnnz[j] = 1;
10313   }
10314   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10315   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10316   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10317   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10318   for (i = rstart/bs; i < rend/bs; i++) {
10319     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10320   }
10321   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10322   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10323   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10324   PetscFunctionReturn(0);
10325 }
10326 
10327 /*@C
10328     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10329     via MatTransposeColoringCreate().
10330 
10331     Collective on MatTransposeColoring
10332 
10333     Input Parameter:
10334 .   c - coloring context
10335 
10336     Level: intermediate
10337 
10338 .seealso: MatTransposeColoringCreate()
10339 @*/
10340 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10341 {
10342   PetscErrorCode       ierr;
10343   MatTransposeColoring matcolor=*c;
10344 
10345   PetscFunctionBegin;
10346   if (!matcolor) PetscFunctionReturn(0);
10347   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10348 
10349   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10350   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10351   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10352   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10353   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10354   if (matcolor->brows>0) {
10355     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10356   }
10357   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10358   PetscFunctionReturn(0);
10359 }
10360 
10361 /*@C
10362     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10363     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10364     MatTransposeColoring to sparse B.
10365 
10366     Collective on MatTransposeColoring
10367 
10368     Input Parameters:
10369 +   B - sparse matrix B
10370 .   Btdense - symbolic dense matrix B^T
10371 -   coloring - coloring context created with MatTransposeColoringCreate()
10372 
10373     Output Parameter:
10374 .   Btdense - dense matrix B^T
10375 
10376     Level: advanced
10377 
10378      Notes: These are used internally for some implementations of MatRARt()
10379 
10380 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10381 
10382 .keywords: coloring
10383 @*/
10384 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10385 {
10386   PetscErrorCode ierr;
10387 
10388   PetscFunctionBegin;
10389   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10390   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10391   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10392 
10393   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10394   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10395   PetscFunctionReturn(0);
10396 }
10397 
10398 /*@C
10399     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10400     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10401     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10402     Csp from Cden.
10403 
10404     Collective on MatTransposeColoring
10405 
10406     Input Parameters:
10407 +   coloring - coloring context created with MatTransposeColoringCreate()
10408 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10409 
10410     Output Parameter:
10411 .   Csp - sparse matrix
10412 
10413     Level: advanced
10414 
10415      Notes: These are used internally for some implementations of MatRARt()
10416 
10417 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10418 
10419 .keywords: coloring
10420 @*/
10421 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10422 {
10423   PetscErrorCode ierr;
10424 
10425   PetscFunctionBegin;
10426   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10427   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10428   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10429 
10430   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10431   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10432   PetscFunctionReturn(0);
10433 }
10434 
10435 /*@C
10436    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10437 
10438    Collective on Mat
10439 
10440    Input Parameters:
10441 +  mat - the matrix product C
10442 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10443 
10444     Output Parameter:
10445 .   color - the new coloring context
10446 
10447     Level: intermediate
10448 
10449 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10450            MatTransColoringApplyDenToSp()
10451 @*/
10452 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10453 {
10454   MatTransposeColoring c;
10455   MPI_Comm             comm;
10456   PetscErrorCode       ierr;
10457 
10458   PetscFunctionBegin;
10459   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10460   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10461   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10462 
10463   c->ctype = iscoloring->ctype;
10464   if (mat->ops->transposecoloringcreate) {
10465     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10466   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10467 
10468   *color = c;
10469   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10470   PetscFunctionReturn(0);
10471 }
10472 
10473 /*@
10474       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10475         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10476         same, otherwise it will be larger
10477 
10478      Not Collective
10479 
10480   Input Parameter:
10481 .    A  - the matrix
10482 
10483   Output Parameter:
10484 .    state - the current state
10485 
10486   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10487          different matrices
10488 
10489   Level: intermediate
10490 
10491 @*/
10492 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10493 {
10494   PetscFunctionBegin;
10495   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10496   *state = mat->nonzerostate;
10497   PetscFunctionReturn(0);
10498 }
10499 
10500 /*@
10501       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10502                  matrices from each processor
10503 
10504     Collective on MPI_Comm
10505 
10506    Input Parameters:
10507 +    comm - the communicators the parallel matrix will live on
10508 .    seqmat - the input sequential matrices
10509 .    n - number of local columns (or PETSC_DECIDE)
10510 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10511 
10512    Output Parameter:
10513 .    mpimat - the parallel matrix generated
10514 
10515     Level: advanced
10516 
10517    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10518 
10519 @*/
10520 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10521 {
10522   PetscErrorCode ierr;
10523 
10524   PetscFunctionBegin;
10525   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10526   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");
10527 
10528   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10529   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10530   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10531   PetscFunctionReturn(0);
10532 }
10533 
10534 /*@
10535      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10536                  ranks' ownership ranges.
10537 
10538     Collective on A
10539 
10540    Input Parameters:
10541 +    A   - the matrix to create subdomains from
10542 -    N   - requested number of subdomains
10543 
10544 
10545    Output Parameters:
10546 +    n   - number of subdomains resulting on this rank
10547 -    iss - IS list with indices of subdomains on this rank
10548 
10549     Level: advanced
10550 
10551     Notes: number of subdomains must be smaller than the communicator size
10552 @*/
10553 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10554 {
10555   MPI_Comm        comm,subcomm;
10556   PetscMPIInt     size,rank,color;
10557   PetscInt        rstart,rend,k;
10558   PetscErrorCode  ierr;
10559 
10560   PetscFunctionBegin;
10561   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10562   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10563   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10564   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);
10565   *n = 1;
10566   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10567   color = rank/k;
10568   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10569   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10570   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10571   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10572   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10573   PetscFunctionReturn(0);
10574 }
10575 
10576 /*@
10577    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10578 
10579    If the interpolation and restriction operators are the same, uses MatPtAP.
10580    If they are not the same, use MatMatMatMult.
10581 
10582    Once the coarse grid problem is constructed, correct for interpolation operators
10583    that are not of full rank, which can legitimately happen in the case of non-nested
10584    geometric multigrid.
10585 
10586    Input Parameters:
10587 +  restrct - restriction operator
10588 .  dA - fine grid matrix
10589 .  interpolate - interpolation operator
10590 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10591 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10592 
10593    Output Parameters:
10594 .  A - the Galerkin coarse matrix
10595 
10596    Options Database Key:
10597 .  -pc_mg_galerkin <both,pmat,mat,none>
10598 
10599    Level: developer
10600 
10601 .keywords: MG, multigrid, Galerkin
10602 
10603 .seealso: MatPtAP(), MatMatMatMult()
10604 @*/
10605 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10606 {
10607   PetscErrorCode ierr;
10608   IS             zerorows;
10609   Vec            diag;
10610 
10611   PetscFunctionBegin;
10612   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10613   /* Construct the coarse grid matrix */
10614   if (interpolate == restrct) {
10615     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10616   } else {
10617     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10618   }
10619 
10620   /* If the interpolation matrix is not of full rank, A will have zero rows.
10621      This can legitimately happen in the case of non-nested geometric multigrid.
10622      In that event, we set the rows of the matrix to the rows of the identity,
10623      ignoring the equations (as the RHS will also be zero). */
10624 
10625   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10626 
10627   if (zerorows != NULL) { /* if there are any zero rows */
10628     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10629     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10630     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10631     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10632     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10633     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10634   }
10635   PetscFunctionReturn(0);
10636 }
10637 
10638 /*@C
10639     MatSetOperation - Allows user to set a matrix operation for any matrix type
10640 
10641    Logically Collective on Mat
10642 
10643     Input Parameters:
10644 +   mat - the matrix
10645 .   op - the name of the operation
10646 -   f - the function that provides the operation
10647 
10648    Level: developer
10649 
10650     Usage:
10651 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10652 $      ierr = MatCreateXXX(comm,...&A);
10653 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10654 
10655     Notes:
10656     See the file include/petscmat.h for a complete list of matrix
10657     operations, which all have the form MATOP_<OPERATION>, where
10658     <OPERATION> is the name (in all capital letters) of the
10659     user interface routine (e.g., MatMult() -> MATOP_MULT).
10660 
10661     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10662     sequence as the usual matrix interface routines, since they
10663     are intended to be accessed via the usual matrix interface
10664     routines, e.g.,
10665 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10666 
10667     In particular each function MUST return an error code of 0 on success and
10668     nonzero on failure.
10669 
10670     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10671 
10672 .keywords: matrix, set, operation
10673 
10674 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10675 @*/
10676 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10677 {
10678   PetscFunctionBegin;
10679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10680   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10681     mat->ops->viewnative = mat->ops->view;
10682   }
10683   (((void(**)(void))mat->ops)[op]) = f;
10684   PetscFunctionReturn(0);
10685 }
10686 
10687 /*@C
10688     MatGetOperation - Gets a matrix operation for any matrix type.
10689 
10690     Not Collective
10691 
10692     Input Parameters:
10693 +   mat - the matrix
10694 -   op - the name of the operation
10695 
10696     Output Parameter:
10697 .   f - the function that provides the operation
10698 
10699     Level: developer
10700 
10701     Usage:
10702 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10703 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10704 
10705     Notes:
10706     See the file include/petscmat.h for a complete list of matrix
10707     operations, which all have the form MATOP_<OPERATION>, where
10708     <OPERATION> is the name (in all capital letters) of the
10709     user interface routine (e.g., MatMult() -> MATOP_MULT).
10710 
10711     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10712 
10713 .keywords: matrix, get, operation
10714 
10715 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10716 @*/
10717 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10718 {
10719   PetscFunctionBegin;
10720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10721   *f = (((void (**)(void))mat->ops)[op]);
10722   PetscFunctionReturn(0);
10723 }
10724 
10725 /*@
10726     MatHasOperation - Determines whether the given matrix supports the particular
10727     operation.
10728 
10729    Not Collective
10730 
10731    Input Parameters:
10732 +  mat - the matrix
10733 -  op - the operation, for example, MATOP_GET_DIAGONAL
10734 
10735    Output Parameter:
10736 .  has - either PETSC_TRUE or PETSC_FALSE
10737 
10738    Level: advanced
10739 
10740    Notes:
10741    See the file include/petscmat.h for a complete list of matrix
10742    operations, which all have the form MATOP_<OPERATION>, where
10743    <OPERATION> is the name (in all capital letters) of the
10744    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10745 
10746 .keywords: matrix, has, operation
10747 
10748 .seealso: MatCreateShell()
10749 @*/
10750 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10751 {
10752   PetscErrorCode ierr;
10753 
10754   PetscFunctionBegin;
10755   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10756   PetscValidType(mat,1);
10757   PetscValidPointer(has,3);
10758   if (mat->ops->hasoperation) {
10759     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10760   } else {
10761     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10762     else {
10763       *has = PETSC_FALSE;
10764       if (op == MATOP_CREATE_SUBMATRIX) {
10765         PetscMPIInt size;
10766 
10767         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10768         if (size == 1) {
10769           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10770         }
10771       }
10772     }
10773   }
10774   PetscFunctionReturn(0);
10775 }
10776