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