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