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