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