xref: /petsc/src/mat/interface/matrix.c (revision bbadc9ee47b9852201359aaea290cac33ff02705)
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_MultAdd, MAT_MultTranspose;
16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis;
36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO;
37 PetscLogEvent MAT_SetValuesBatch;
38 PetscLogEvent MAT_ViennaCLCopyToGPU;
39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU;
40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS;
42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR;
44 
45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL};
46 
47 /*@
48    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,
49                   for sparse matrices that already have locations it fills the locations with random numbers
50 
51    Logically Collective on Mat
52 
53    Input Parameters:
54 +  x  - the matrix
55 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
56           it will create one internally.
57 
58    Output Parameter:
59 .  x  - the matrix
60 
61    Example of Usage:
62 .vb
63      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
64      MatSetRandom(x,rctx);
65      PetscRandomDestroy(rctx);
66 .ve
67 
68    Level: intermediate
69 
70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
71 @*/
72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
73 {
74   PetscRandom    randObj = NULL;
75 
76   PetscFunctionBegin;
77   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
78   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
79   PetscValidType(x,1);
80   MatCheckPreallocated(x,1);
81 
82   PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
83 
84   if (!rctx) {
85     MPI_Comm comm;
86     PetscCall(PetscObjectGetComm((PetscObject)x,&comm));
87     PetscCall(PetscRandomCreate(comm,&randObj));
88     PetscCall(PetscRandomSetFromOptions(randObj));
89     rctx = randObj;
90   }
91   PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0));
92   PetscCall((*x->ops->setrandom)(x,rctx));
93   PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0));
94 
95   PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY));
96   PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY));
97   PetscCall(PetscRandomDestroy(&randObj));
98   PetscFunctionReturn(0);
99 }
100 
101 /*@
102    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
103 
104    Logically Collective on Mat
105 
106    Input Parameter:
107 .  mat - the factored matrix
108 
109    Output Parameters:
110 +  pivot - the pivot value computed
111 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
112          the share the matrix
113 
114    Level: advanced
115 
116    Notes:
117     This routine does not work for factorizations done with external packages.
118 
119     This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
120 
121     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
122 
123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`
124 @*/
125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
126 {
127   PetscFunctionBegin;
128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
129   PetscValidRealPointer(pivot,2);
130   PetscValidIntPointer(row,3);
131   *pivot = mat->factorerror_zeropivot_value;
132   *row   = mat->factorerror_zeropivot_row;
133   PetscFunctionReturn(0);
134 }
135 
136 /*@
137    MatFactorGetError - gets the error code from a factorization
138 
139    Logically Collective on Mat
140 
141    Input Parameters:
142 .  mat - the factored matrix
143 
144    Output Parameter:
145 .  err  - the error code
146 
147    Level: advanced
148 
149    Notes:
150     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
151 
152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`
153 @*/
154 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
155 {
156   PetscFunctionBegin;
157   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
158   PetscValidPointer(err,2);
159   *err = mat->factorerrortype;
160   PetscFunctionReturn(0);
161 }
162 
163 /*@
164    MatFactorClearError - clears the error code in a factorization
165 
166    Logically Collective on Mat
167 
168    Input Parameter:
169 .  mat - the factored matrix
170 
171    Level: developer
172 
173    Notes:
174     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
175 
176 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`
177 @*/
178 PetscErrorCode MatFactorClearError(Mat mat)
179 {
180   PetscFunctionBegin;
181   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
182   mat->factorerrortype             = MAT_FACTOR_NOERROR;
183   mat->factorerror_zeropivot_value = 0.0;
184   mat->factorerror_zeropivot_row   = 0;
185   PetscFunctionReturn(0);
186 }
187 
188 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
189 {
190   Vec               r,l;
191   const PetscScalar *al;
192   PetscInt          i,nz,gnz,N,n;
193 
194   PetscFunctionBegin;
195   PetscCall(MatCreateVecs(mat,&r,&l));
196   if (!cols) { /* nonzero rows */
197     PetscCall(MatGetSize(mat,&N,NULL));
198     PetscCall(MatGetLocalSize(mat,&n,NULL));
199     PetscCall(VecSet(l,0.0));
200     PetscCall(VecSetRandom(r,NULL));
201     PetscCall(MatMult(mat,r,l));
202     PetscCall(VecGetArrayRead(l,&al));
203   } else { /* nonzero columns */
204     PetscCall(MatGetSize(mat,NULL,&N));
205     PetscCall(MatGetLocalSize(mat,NULL,&n));
206     PetscCall(VecSet(r,0.0));
207     PetscCall(VecSetRandom(l,NULL));
208     PetscCall(MatMultTranspose(mat,l,r));
209     PetscCall(VecGetArrayRead(r,&al));
210   }
211   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
212   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
213   PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat)));
214   if (gnz != N) {
215     PetscInt *nzr;
216     PetscCall(PetscMalloc1(nz,&nzr));
217     if (nz) {
218       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
219       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
220     }
221     PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero));
222   } else *nonzero = NULL;
223   if (!cols) { /* nonzero rows */
224     PetscCall(VecRestoreArrayRead(l,&al));
225   } else {
226     PetscCall(VecRestoreArrayRead(r,&al));
227   }
228   PetscCall(VecDestroy(&l));
229   PetscCall(VecDestroy(&r));
230   PetscFunctionReturn(0);
231 }
232 
233 /*@
234       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
235 
236   Input Parameter:
237 .    A  - the matrix
238 
239   Output Parameter:
240 .    keptrows - the rows that are not completely zero
241 
242   Notes:
243     keptrows is set to NULL if all rows are nonzero.
244 
245   Level: intermediate
246 
247  @*/
248 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
249 {
250   PetscFunctionBegin;
251   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
252   PetscValidType(mat,1);
253   PetscValidPointer(keptrows,2);
254   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
255   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
256   if (mat->ops->findnonzerorows) {
257     PetscCall((*mat->ops->findnonzerorows)(mat,keptrows));
258   } else {
259     PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows));
260   }
261   PetscFunctionReturn(0);
262 }
263 
264 /*@
265       MatFindZeroRows - Locate all rows that are completely zero in the matrix
266 
267   Input Parameter:
268 .    A  - the matrix
269 
270   Output Parameter:
271 .    zerorows - the rows that are completely zero
272 
273   Notes:
274     zerorows is set to NULL if no rows are zero.
275 
276   Level: intermediate
277 
278  @*/
279 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
280 {
281   IS       keptrows;
282   PetscInt m, n;
283 
284   PetscFunctionBegin;
285   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
286   PetscValidType(mat,1);
287   PetscValidPointer(zerorows,2);
288   PetscCall(MatFindNonzeroRows(mat, &keptrows));
289   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
290      In keeping with this convention, we set zerorows to NULL if there are no zero
291      rows. */
292   if (keptrows == NULL) {
293     *zerorows = NULL;
294   } else {
295     PetscCall(MatGetOwnershipRange(mat,&m,&n));
296     PetscCall(ISComplement(keptrows,m,n,zerorows));
297     PetscCall(ISDestroy(&keptrows));
298   }
299   PetscFunctionReturn(0);
300 }
301 
302 /*@
303    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
304 
305    Not Collective
306 
307    Input Parameters:
308 .   A - the matrix
309 
310    Output Parameters:
311 .   a - the diagonal part (which is a SEQUENTIAL matrix)
312 
313    Notes:
314     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
315           Use caution, as the reference count on the returned matrix is not incremented and it is used as
316           part of the containing MPI Mat's normal operation.
317 
318    Level: advanced
319 
320 @*/
321 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
322 {
323   PetscFunctionBegin;
324   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
325   PetscValidType(A,1);
326   PetscValidPointer(a,2);
327   PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
328   if (A->ops->getdiagonalblock) {
329     PetscCall((*A->ops->getdiagonalblock)(A,a));
330   } else {
331     PetscMPIInt size;
332 
333     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size));
334     PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name);
335     *a = A;
336   }
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   Vec diag;
357 
358   PetscFunctionBegin;
359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
360   PetscValidScalarPointer(trace,2);
361   PetscCall(MatCreateVecs(mat,&diag,NULL));
362   PetscCall(MatGetDiagonal(mat,diag));
363   PetscCall(VecSum(diag,trace));
364   PetscCall(VecDestroy(&diag));
365   PetscFunctionReturn(0);
366 }
367 
368 /*@
369    MatRealPart - Zeros out the imaginary part of the matrix
370 
371    Logically Collective on Mat
372 
373    Input Parameters:
374 .  mat - the matrix
375 
376    Level: advanced
377 
378 .seealso: `MatImaginaryPart()`
379 @*/
380 PetscErrorCode MatRealPart(Mat mat)
381 {
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
384   PetscValidType(mat,1);
385   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
386   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
387   PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
388   MatCheckPreallocated(mat,1);
389   PetscCall((*mat->ops->realpart)(mat));
390   PetscFunctionReturn(0);
391 }
392 
393 /*@C
394    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
395 
396    Collective on Mat
397 
398    Input Parameter:
399 .  mat - the matrix
400 
401    Output Parameters:
402 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
403 -   ghosts - the global indices of the ghost points
404 
405    Notes:
406     the nghosts and ghosts are suitable to pass into VecCreateGhost()
407 
408    Level: advanced
409 
410 @*/
411 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
412 {
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
415   PetscValidType(mat,1);
416   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
417   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
418   if (mat->ops->getghosts) {
419     PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts));
420   } else {
421     if (nghosts) *nghosts = 0;
422     if (ghosts)  *ghosts  = NULL;
423   }
424   PetscFunctionReturn(0);
425 }
426 
427 /*@
428    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
429 
430    Logically Collective on Mat
431 
432    Input Parameters:
433 .  mat - the matrix
434 
435    Level: advanced
436 
437 .seealso: `MatRealPart()`
438 @*/
439 PetscErrorCode MatImaginaryPart(Mat mat)
440 {
441   PetscFunctionBegin;
442   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
443   PetscValidType(mat,1);
444   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
445   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
446   PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
447   MatCheckPreallocated(mat,1);
448   PetscCall((*mat->ops->imaginarypart)(mat));
449   PetscFunctionReturn(0);
450 }
451 
452 /*@
453    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
454 
455    Not Collective
456 
457    Input Parameter:
458 .  mat - the matrix
459 
460    Output Parameters:
461 +  missing - is any diagonal missing
462 -  dd - first diagonal entry that is missing (optional) on this process
463 
464    Level: advanced
465 
466 .seealso: `MatRealPart()`
467 @*/
468 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
469 {
470   PetscFunctionBegin;
471   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
472   PetscValidType(mat,1);
473   PetscValidBoolPointer(missing,2);
474   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name);
475   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
476   PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
477   PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd));
478   PetscFunctionReturn(0);
479 }
480 
481 /*@C
482    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
483    for each row that you get to ensure that your application does
484    not bleed memory.
485 
486    Not Collective
487 
488    Input Parameters:
489 +  mat - the matrix
490 -  row - the row to get
491 
492    Output Parameters:
493 +  ncols -  if not NULL, the number of nonzeros in the row
494 .  cols - if not NULL, the column numbers
495 -  vals - if not NULL, the values
496 
497    Notes:
498    This routine is provided for people who need to have direct access
499    to the structure of a matrix.  We hope that we provide enough
500    high-level matrix routines that few users will need it.
501 
502    MatGetRow() always returns 0-based column indices, regardless of
503    whether the internal representation is 0-based (default) or 1-based.
504 
505    For better efficiency, set cols and/or vals to NULL if you do
506    not wish to extract these quantities.
507 
508    The user can only examine the values extracted with MatGetRow();
509    the values cannot be altered.  To change the matrix entries, one
510    must use MatSetValues().
511 
512    You can only have one call to MatGetRow() outstanding for a particular
513    matrix at a time, per processor. MatGetRow() can only obtain rows
514    associated with the given processor, it cannot get rows from the
515    other processors; for that we suggest using MatCreateSubMatrices(), then
516    MatGetRow() on the submatrix. The row index passed to MatGetRow()
517    is in the global number of rows.
518 
519    Fortran Notes:
520    The calling sequence from Fortran is
521 .vb
522    MatGetRow(matrix,row,ncols,cols,values,ierr)
523          Mat     matrix (input)
524          integer row    (input)
525          integer ncols  (output)
526          integer cols(maxcols) (output)
527          double precision (or double complex) values(maxcols) output
528 .ve
529    where maxcols >= maximum nonzeros in any row of the matrix.
530 
531    Caution:
532    Do not try to change the contents of the output arrays (cols and vals).
533    In some cases, this may corrupt the matrix.
534 
535    Level: advanced
536 
537 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`
538 @*/
539 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
540 {
541   PetscInt incols;
542 
543   PetscFunctionBegin;
544   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
545   PetscValidType(mat,1);
546   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
547   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
548   PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
549   MatCheckPreallocated(mat,1);
550   PetscCheck(row >= mat->rmap->rstart && row < mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend);
551   PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0));
552   PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals));
553   if (ncols) *ncols = incols;
554   PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0));
555   PetscFunctionReturn(0);
556 }
557 
558 /*@
559    MatConjugate - replaces the matrix values with their complex conjugates
560 
561    Logically Collective on Mat
562 
563    Input Parameters:
564 .  mat - the matrix
565 
566    Level: advanced
567 
568 .seealso: `VecConjugate()`
569 @*/
570 PetscErrorCode MatConjugate(Mat mat)
571 {
572   PetscFunctionBegin;
573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
574   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
575   if (PetscDefined(USE_COMPLEX)) {
576     PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name);
577     PetscCall((*mat->ops->conjugate)(mat));
578   }
579   PetscFunctionReturn(0);
580 }
581 
582 /*@C
583    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
584 
585    Not Collective
586 
587    Input Parameters:
588 +  mat - the matrix
589 .  row - the row to get
590 .  ncols, cols - the number of nonzeros and their columns
591 -  vals - if nonzero the column values
592 
593    Notes:
594    This routine should be called after you have finished examining the entries.
595 
596    This routine zeros out ncols, cols, and vals. This is to prevent accidental
597    us of the array after it has been restored. If you pass NULL, it will
598    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
599 
600    Fortran Notes:
601    The calling sequence from Fortran is
602 .vb
603    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
604       Mat     matrix (input)
605       integer row    (input)
606       integer ncols  (output)
607       integer cols(maxcols) (output)
608       double precision (or double complex) values(maxcols) output
609 .ve
610    Where maxcols >= maximum nonzeros in any row of the matrix.
611 
612    In Fortran MatRestoreRow() MUST be called after MatGetRow()
613    before another call to MatGetRow() can be made.
614 
615    Level: advanced
616 
617 .seealso: `MatGetRow()`
618 @*/
619 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
620 {
621   PetscFunctionBegin;
622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
623   if (ncols) PetscValidIntPointer(ncols,3);
624   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
625   if (!mat->ops->restorerow) PetscFunctionReturn(0);
626   PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals));
627   if (ncols) *ncols = 0;
628   if (cols)  *cols = NULL;
629   if (vals)  *vals = NULL;
630   PetscFunctionReturn(0);
631 }
632 
633 /*@
634    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
635    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
636 
637    Not Collective
638 
639    Input Parameters:
640 .  mat - the matrix
641 
642    Notes:
643    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.
644 
645    Level: advanced
646 
647 .seealso: `MatRestoreRowUpperTriangular()`
648 @*/
649 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
650 {
651   PetscFunctionBegin;
652   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
653   PetscValidType(mat,1);
654   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
655   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
656   MatCheckPreallocated(mat,1);
657   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
658   PetscCall((*mat->ops->getrowuppertriangular)(mat));
659   PetscFunctionReturn(0);
660 }
661 
662 /*@
663    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
664 
665    Not Collective
666 
667    Input Parameters:
668 .  mat - the matrix
669 
670    Notes:
671    This routine should be called after you have finished MatGetRow/MatRestoreRow().
672 
673    Level: advanced
674 
675 .seealso: `MatGetRowUpperTriangular()`
676 @*/
677 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
678 {
679   PetscFunctionBegin;
680   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
681   PetscValidType(mat,1);
682   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
683   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
684   MatCheckPreallocated(mat,1);
685   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
686   PetscCall((*mat->ops->restorerowuppertriangular)(mat));
687   PetscFunctionReturn(0);
688 }
689 
690 /*@C
691    MatSetOptionsPrefix - Sets the prefix used for searching for all
692    Mat options in the database.
693 
694    Logically Collective on Mat
695 
696    Input Parameters:
697 +  A - the Mat context
698 -  prefix - the prefix to prepend to all option names
699 
700    Notes:
701    A hyphen (-) must NOT be given at the beginning of the prefix name.
702    The first character of all runtime options is AUTOMATICALLY the hyphen.
703 
704    Level: advanced
705 
706 .seealso: `MatSetFromOptions()`
707 @*/
708 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
709 {
710   PetscFunctionBegin;
711   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
712   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix));
713   PetscFunctionReturn(0);
714 }
715 
716 /*@C
717    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
718    Mat options in the database.
719 
720    Logically Collective on Mat
721 
722    Input Parameters:
723 +  A - the Mat context
724 -  prefix - the prefix to prepend to all option names
725 
726    Notes:
727    A hyphen (-) must NOT be given at the beginning of the prefix name.
728    The first character of all runtime options is AUTOMATICALLY the hyphen.
729 
730    Level: advanced
731 
732 .seealso: `MatGetOptionsPrefix()`
733 @*/
734 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
735 {
736   PetscFunctionBegin;
737   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
738   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix));
739   PetscFunctionReturn(0);
740 }
741 
742 /*@C
743    MatGetOptionsPrefix - Gets the prefix used for searching for all
744    Mat options in the database.
745 
746    Not Collective
747 
748    Input Parameter:
749 .  A - the Mat context
750 
751    Output Parameter:
752 .  prefix - pointer to the prefix string used
753 
754    Notes:
755     On the fortran side, the user should pass in a string 'prefix' of
756    sufficient length to hold the prefix.
757 
758    Level: advanced
759 
760 .seealso: `MatAppendOptionsPrefix()`
761 @*/
762 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
763 {
764   PetscFunctionBegin;
765   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
766   PetscValidPointer(prefix,2);
767   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix));
768   PetscFunctionReturn(0);
769 }
770 
771 /*@
772    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
773 
774    Collective on Mat
775 
776    Input Parameters:
777 .  A - the Mat context
778 
779    Notes:
780    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
781    Currently support MPIAIJ and SEQAIJ.
782 
783    Level: beginner
784 
785 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()`
786 @*/
787 PetscErrorCode MatResetPreallocation(Mat A)
788 {
789   PetscFunctionBegin;
790   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
791   PetscValidType(A,1);
792   PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));
793   PetscFunctionReturn(0);
794 }
795 
796 /*@
797    MatSetUp - Sets up the internal matrix data structures for later use.
798 
799    Collective on Mat
800 
801    Input Parameters:
802 .  A - the Mat context
803 
804    Notes:
805    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
806 
807    If a suitable preallocation routine is used, this function does not need to be called.
808 
809    See the Performance chapter of the PETSc users manual for how to preallocate matrices
810 
811    Level: beginner
812 
813 .seealso: `MatCreate()`, `MatDestroy()`
814 @*/
815 PetscErrorCode MatSetUp(Mat A)
816 {
817   PetscFunctionBegin;
818   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
819   if (!((PetscObject)A)->type_name) {
820     PetscMPIInt size;
821 
822     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size));
823     PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ));
824   }
825   if (!A->preallocated && A->ops->setup) {
826     PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n"));
827     PetscCall((*A->ops->setup)(A));
828   }
829   PetscCall(PetscLayoutSetUp(A->rmap));
830   PetscCall(PetscLayoutSetUp(A->cmap));
831   A->preallocated = PETSC_TRUE;
832   PetscFunctionReturn(0);
833 }
834 
835 #if defined(PETSC_HAVE_SAWS)
836 #include <petscviewersaws.h>
837 #endif
838 
839 /*@C
840    MatViewFromOptions - View from Options
841 
842    Collective on Mat
843 
844    Input Parameters:
845 +  A - the Mat context
846 .  obj - Optional object
847 -  name - command line option
848 
849    Level: intermediate
850 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()`
851 @*/
852 PetscErrorCode  MatViewFromOptions(Mat A,PetscObject obj,const char name[])
853 {
854   PetscFunctionBegin;
855   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
856   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
857   PetscFunctionReturn(0);
858 }
859 
860 /*@C
861    MatView - Visualizes a matrix object.
862 
863    Collective on Mat
864 
865    Input Parameters:
866 +  mat - the matrix
867 -  viewer - visualization context
868 
869   Notes:
870   The available visualization contexts include
871 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
872 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
873 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
874 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
875 
876    The user can open alternative visualization contexts with
877 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
878 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
879          specified file; corresponding input uses MatLoad()
880 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
881          an X window display
882 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
883          Currently only the sequential dense and AIJ
884          matrix types support the Socket viewer.
885 
886    The user can call PetscViewerPushFormat() to specify the output
887    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
888    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
889 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
890 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
891 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
892 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
893          format common among all matrix types
894 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
895          format (which is in many cases the same as the default)
896 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
897          size and structure (not the matrix entries)
898 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
899          the matrix structure
900 
901    Options Database Keys:
902 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
903 .  -mat_view ::ascii_info_detail - Prints more detailed info
904 .  -mat_view - Prints matrix in ASCII format
905 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
906 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
907 .  -display <name> - Sets display name (default is host)
908 .  -draw_pause <sec> - Sets number of seconds to pause after display
909 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
910 .  -viewer_socket_machine <machine> -
911 .  -viewer_socket_port <port> -
912 .  -mat_view binary - save matrix to file in binary format
913 -  -viewer_binary_filename <name> -
914 
915    Level: beginner
916 
917    Notes:
918     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
919     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
920 
921     In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer).
922 
923     See the manual page for MatLoad() for the exact format of the binary file when the binary
924       viewer is used.
925 
926       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
927       viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python.
928 
929       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
930       and then use the following mouse functions.
931 .vb
932   left mouse: zoom in
933   middle mouse: zoom out
934   right mouse: continue with the simulation
935 .ve
936 
937 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
938           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()`
939 @*/
940 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
941 {
942   PetscInt          rows,cols,rbs,cbs;
943   PetscBool         isascii,isstring,issaws;
944   PetscViewerFormat format;
945   PetscMPIInt       size;
946 
947   PetscFunctionBegin;
948   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
949   PetscValidType(mat,1);
950   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer));
951   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
952   PetscCheckSameComm(mat,1,viewer,2);
953   MatCheckPreallocated(mat,1);
954 
955   PetscCall(PetscViewerGetFormat(viewer,&format));
956   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
957   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
958 
959   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
960   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
961   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws));
962   if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
963     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail");
964   }
965 
966   PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0));
967   if (isascii) {
968     PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
969     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer));
970     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
971       MatNullSpace nullsp,transnullsp;
972 
973       PetscCall(PetscViewerASCIIPushTab(viewer));
974       PetscCall(MatGetSize(mat,&rows,&cols));
975       PetscCall(MatGetBlockSizes(mat,&rbs,&cbs));
976       if (rbs != 1 || cbs != 1) {
977         if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs));
978         else            PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs));
979       } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols));
980       if (mat->factortype) {
981         MatSolverType solver;
982         PetscCall(MatFactorGetSolverType(mat,&solver));
983         PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver));
984       }
985       if (mat->ops->getinfo) {
986         MatInfo info;
987         PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info));
988         PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated));
989         if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs));
990       }
991       PetscCall(MatGetNullSpace(mat,&nullsp));
992       PetscCall(MatGetTransposeNullSpace(mat,&transnullsp));
993       if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer,"  has attached null space\n"));
994       if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n"));
995       PetscCall(MatGetNearNullSpace(mat,&nullsp));
996       if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer,"  has attached near null space\n"));
997       PetscCall(PetscViewerASCIIPushTab(viewer));
998       PetscCall(MatProductView(mat,viewer));
999       PetscCall(PetscViewerASCIIPopTab(viewer));
1000     }
1001   } else if (issaws) {
1002 #if defined(PETSC_HAVE_SAWS)
1003     PetscMPIInt rank;
1004 
1005     PetscCall(PetscObjectName((PetscObject)mat));
1006     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
1007     if (!((PetscObject)mat)->amsmem && rank == 0) {
1008       PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer));
1009     }
1010 #endif
1011   } else if (isstring) {
1012     const char *type;
1013     PetscCall(MatGetType(mat,&type));
1014     PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type));
1015     if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer));
1016   }
1017   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1018     PetscCall(PetscViewerASCIIPushTab(viewer));
1019     PetscCall((*mat->ops->viewnative)(mat,viewer));
1020     PetscCall(PetscViewerASCIIPopTab(viewer));
1021   } else if (mat->ops->view) {
1022     PetscCall(PetscViewerASCIIPushTab(viewer));
1023     PetscCall((*mat->ops->view)(mat,viewer));
1024     PetscCall(PetscViewerASCIIPopTab(viewer));
1025   }
1026   if (isascii) {
1027     PetscCall(PetscViewerGetFormat(viewer,&format));
1028     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1029       PetscCall(PetscViewerASCIIPopTab(viewer));
1030     }
1031   }
1032   PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0));
1033   PetscFunctionReturn(0);
1034 }
1035 
1036 #if defined(PETSC_USE_DEBUG)
1037 #include <../src/sys/totalview/tv_data_display.h>
1038 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1039 {
1040   TV_add_row("Local rows", "int", &mat->rmap->n);
1041   TV_add_row("Local columns", "int", &mat->cmap->n);
1042   TV_add_row("Global rows", "int", &mat->rmap->N);
1043   TV_add_row("Global columns", "int", &mat->cmap->N);
1044   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1045   return TV_format_OK;
1046 }
1047 #endif
1048 
1049 /*@C
1050    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1051    with MatView().  The matrix format is determined from the options database.
1052    Generates a parallel MPI matrix if the communicator has more than one
1053    processor.  The default matrix type is AIJ.
1054 
1055    Collective on PetscViewer
1056 
1057    Input Parameters:
1058 +  mat - the newly loaded matrix, this needs to have been created with MatCreate()
1059             or some related function before a call to MatLoad()
1060 -  viewer - binary/HDF5 file viewer
1061 
1062    Options Database Keys:
1063    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1064    block size
1065 .    -matload_block_size <bs> - set block size
1066 
1067    Level: beginner
1068 
1069    Notes:
1070    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1071    Mat before calling this routine if you wish to set it from the options database.
1072 
1073    MatLoad() automatically loads into the options database any options
1074    given in the file filename.info where filename is the name of the file
1075    that was passed to the PetscViewerBinaryOpen(). The options in the info
1076    file will be ignored if you use the -viewer_binary_skip_info option.
1077 
1078    If the type or size of mat is not set before a call to MatLoad, PETSc
1079    sets the default matrix type AIJ and sets the local and global sizes.
1080    If type and/or size is already set, then the same are used.
1081 
1082    In parallel, each processor can load a subset of rows (or the
1083    entire matrix).  This routine is especially useful when a large
1084    matrix is stored on disk and only part of it is desired on each
1085    processor.  For example, a parallel solver may access only some of
1086    the rows from each processor.  The algorithm used here reads
1087    relatively small blocks of data rather than reading the entire
1088    matrix and then subsetting it.
1089 
1090    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1091    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1092    or the sequence like
1093 $    PetscViewer v;
1094 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1095 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1096 $    PetscViewerSetFromOptions(v);
1097 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1098 $    PetscViewerFileSetName(v,"datafile");
1099    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1100 $ -viewer_type {binary,hdf5}
1101 
1102    See the example src/ksp/ksp/tutorials/ex27.c with the first approach,
1103    and src/mat/tutorials/ex10.c with the second approach.
1104 
1105    Notes about the PETSc binary format:
1106    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1107    is read onto rank 0 and then shipped to its destination rank, one after another.
1108    Multiple objects, both matrices and vectors, can be stored within the same file.
1109    Their PetscObject name is ignored; they are loaded in the order of their storage.
1110 
1111    Most users should not need to know the details of the binary storage
1112    format, since MatLoad() and MatView() completely hide these details.
1113    But for anyone who's interested, the standard binary matrix storage
1114    format is
1115 
1116 $    PetscInt    MAT_FILE_CLASSID
1117 $    PetscInt    number of rows
1118 $    PetscInt    number of columns
1119 $    PetscInt    total number of nonzeros
1120 $    PetscInt    *number nonzeros in each row
1121 $    PetscInt    *column indices of all nonzeros (starting index is zero)
1122 $    PetscScalar *values of all nonzeros
1123 
1124    PETSc automatically does the byte swapping for
1125 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1126 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary
1127 read/write routines you have to swap the bytes; see PetscBinaryRead()
1128 and PetscBinaryWrite() to see how this may be done.
1129 
1130    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1131    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1132    Each processor's chunk is loaded independently by its owning rank.
1133    Multiple objects, both matrices and vectors, can be stored within the same file.
1134    They are looked up by their PetscObject name.
1135 
1136    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1137    by default the same structure and naming of the AIJ arrays and column count
1138    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1139 $    save example.mat A b -v7.3
1140    can be directly read by this routine (see Reference 1 for details).
1141    Note that depending on your MATLAB version, this format might be a default,
1142    otherwise you can set it as default in Preferences.
1143 
1144    Unless -nocompression flag is used to save the file in MATLAB,
1145    PETSc must be configured with ZLIB package.
1146 
1147    See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c
1148 
1149    Current HDF5 (MAT-File) limitations:
1150    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1151 
1152    Corresponding MatView() is not yet implemented.
1153 
1154    The loaded matrix is actually a transpose of the original one in MATLAB,
1155    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1156    With this format, matrix is automatically transposed by PETSc,
1157    unless the matrix is marked as SPD or symmetric
1158    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1159 
1160    References:
1161 .  * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1162 
1163 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()`
1164 
1165  @*/
1166 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer)
1167 {
1168   PetscBool flg;
1169 
1170   PetscFunctionBegin;
1171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1172   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1173 
1174   if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ));
1175 
1176   flg  = PETSC_FALSE;
1177   PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL));
1178   if (flg) {
1179     PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE));
1180     PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE));
1181   }
1182   flg  = PETSC_FALSE;
1183   PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL));
1184   if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE));
1185 
1186   PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name);
1187   PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0));
1188   PetscCall((*mat->ops->load)(mat,viewer));
1189   PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0));
1190   PetscFunctionReturn(0);
1191 }
1192 
1193 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1194 {
1195   Mat_Redundant *redund = *redundant;
1196 
1197   PetscFunctionBegin;
1198   if (redund) {
1199     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1200       PetscCall(ISDestroy(&redund->isrow));
1201       PetscCall(ISDestroy(&redund->iscol));
1202       PetscCall(MatDestroySubMatrices(1,&redund->matseq));
1203     } else {
1204       PetscCall(PetscFree2(redund->send_rank,redund->recv_rank));
1205       PetscCall(PetscFree(redund->sbuf_j));
1206       PetscCall(PetscFree(redund->sbuf_a));
1207       for (PetscInt i=0; i<redund->nrecvs; i++) {
1208         PetscCall(PetscFree(redund->rbuf_j[i]));
1209         PetscCall(PetscFree(redund->rbuf_a[i]));
1210       }
1211       PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a));
1212     }
1213 
1214     if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm));
1215     PetscCall(PetscFree(redund));
1216   }
1217   PetscFunctionReturn(0);
1218 }
1219 
1220 /*@C
1221    MatDestroy - Frees space taken by a matrix.
1222 
1223    Collective on Mat
1224 
1225    Input Parameter:
1226 .  A - the matrix
1227 
1228    Level: beginner
1229 
1230    Developer Notes:
1231    Some special arrays of matrices are not destroyed in this routine but instead by the routines called by
1232    MatDestroySubMatrices(). Thus one must be sure that any changes here must also be made in those routines.
1233    MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the Mat object and likely need changes
1234    if changes are needed here.
1235 @*/
1236 PetscErrorCode MatDestroy(Mat *A)
1237 {
1238   PetscFunctionBegin;
1239   if (!*A) PetscFunctionReturn(0);
1240   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1241   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1242 
1243   /* if memory was published with SAWs then destroy it */
1244   PetscCall(PetscObjectSAWsViewOff((PetscObject)*A));
1245   if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A));
1246 
1247   PetscCall(PetscFree((*A)->defaultvectype));
1248   PetscCall(PetscFree((*A)->bsizes));
1249   PetscCall(PetscFree((*A)->solvertype));
1250   for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i]));
1251   PetscCall(MatDestroy_Redundant(&(*A)->redundant));
1252   PetscCall(MatProductClear(*A));
1253   PetscCall(MatNullSpaceDestroy(&(*A)->nullsp));
1254   PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp));
1255   PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp));
1256   PetscCall(MatDestroy(&(*A)->schur));
1257   PetscCall(PetscLayoutDestroy(&(*A)->rmap));
1258   PetscCall(PetscLayoutDestroy(&(*A)->cmap));
1259   PetscCall(PetscHeaderDestroy(A));
1260   PetscFunctionReturn(0);
1261 }
1262 
1263 /*@C
1264    MatSetValues - Inserts or adds a block of values into a matrix.
1265    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1266    MUST be called after all calls to MatSetValues() have been completed.
1267 
1268    Not Collective
1269 
1270    Input Parameters:
1271 +  mat - the matrix
1272 .  v - a logically two-dimensional array of values
1273 .  m, idxm - the number of rows and their global indices
1274 .  n, idxn - the number of columns and their global indices
1275 -  addv - either ADD_VALUES or INSERT_VALUES, where
1276    ADD_VALUES adds values to any existing entries, and
1277    INSERT_VALUES replaces existing entries with new values
1278 
1279    Notes:
1280    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1281       MatSetUp() before using this routine
1282 
1283    By default the values, v, are row-oriented. See MatSetOption() for other options.
1284 
1285    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1286    options cannot be mixed without intervening calls to the assembly
1287    routines.
1288 
1289    MatSetValues() uses 0-based row and column numbers in Fortran
1290    as well as in C.
1291 
1292    Negative indices may be passed in idxm and idxn, these rows and columns are
1293    simply ignored. This allows easily inserting element stiffness matrices
1294    with homogeneous Dirchlet boundary conditions that you don't want represented
1295    in the matrix.
1296 
1297    Efficiency Alert:
1298    The routine MatSetValuesBlocked() may offer much better efficiency
1299    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1300 
1301    Level: beginner
1302 
1303    Developer Notes:
1304     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1305                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1306 
1307 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`,
1308           `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`
1309 @*/
1310 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1311 {
1312   PetscFunctionBeginHot;
1313   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1314   PetscValidType(mat,1);
1315   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1316   PetscValidIntPointer(idxm,3);
1317   PetscValidIntPointer(idxn,5);
1318   MatCheckPreallocated(mat,1);
1319 
1320   if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv;
1321   else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1322 
1323   if (PetscDefined(USE_DEBUG)) {
1324     PetscInt       i,j;
1325 
1326     PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1327     PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1328 
1329     for (i=0; i<m; i++) {
1330       for (j=0; j<n; j++) {
1331         if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1332 #if defined(PETSC_USE_COMPLEX)
1333           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1334 #else
1335           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]);
1336 #endif
1337       }
1338     }
1339     for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1);
1340     for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1);
1341   }
1342 
1343   if (mat->assembled) {
1344     mat->was_assembled = PETSC_TRUE;
1345     mat->assembled     = PETSC_FALSE;
1346   }
1347   PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0));
1348   PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv));
1349   PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0));
1350   PetscFunctionReturn(0);
1351 }
1352 
1353 /*@C
1354    MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns
1355    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1356    MUST be called after all calls to MatSetValues() have been completed.
1357 
1358    Not Collective
1359 
1360    Input Parameters:
1361 +  mat - the matrix
1362 .  v - a logically two-dimensional array of values
1363 .  ism - the rows to provide
1364 .  isn - the columns to provide
1365 -  addv - either ADD_VALUES or INSERT_VALUES, where
1366    ADD_VALUES adds values to any existing entries, and
1367    INSERT_VALUES replaces existing entries with new values
1368 
1369    Notes:
1370    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1371       MatSetUp() before using this routine
1372 
1373    By default the values, v, are row-oriented. See MatSetOption() for other options.
1374 
1375    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1376    options cannot be mixed without intervening calls to the assembly
1377    routines.
1378 
1379    MatSetValues() uses 0-based row and column numbers in Fortran
1380    as well as in C.
1381 
1382    Negative indices may be passed in ism and isn, these rows and columns are
1383    simply ignored. This allows easily inserting element stiffness matrices
1384    with homogeneous Dirchlet boundary conditions that you don't want represented
1385    in the matrix.
1386 
1387    Efficiency Alert:
1388    The routine MatSetValuesBlocked() may offer much better efficiency
1389    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1390 
1391    Level: beginner
1392 
1393    Developer Notes:
1394     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1395                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1396 
1397     This is currently not optimized for any particular IS type
1398 
1399 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1400           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1401 @*/
1402 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv)
1403 {
1404   PetscInt       m,n;
1405   const PetscInt *rows,*cols;
1406 
1407   PetscFunctionBeginHot;
1408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1409   PetscCall(ISGetIndices(ism,&rows));
1410   PetscCall(ISGetIndices(isn,&cols));
1411   PetscCall(ISGetLocalSize(ism,&m));
1412   PetscCall(ISGetLocalSize(isn,&n));
1413   PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv));
1414   PetscCall(ISRestoreIndices(ism,&rows));
1415   PetscCall(ISRestoreIndices(isn,&cols));
1416   PetscFunctionReturn(0);
1417 }
1418 
1419 /*@
1420    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1421         values into a matrix
1422 
1423    Not Collective
1424 
1425    Input Parameters:
1426 +  mat - the matrix
1427 .  row - the (block) row to set
1428 -  v - a logically two-dimensional array of values
1429 
1430    Notes:
1431    By the values, v, are column-oriented (for the block version) and sorted
1432 
1433    All the nonzeros in the row must be provided
1434 
1435    The matrix must have previously had its column indices set
1436 
1437    The row must belong to this process
1438 
1439    Level: intermediate
1440 
1441 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`,
1442           `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()`
1443 @*/
1444 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1445 {
1446   PetscInt globalrow;
1447 
1448   PetscFunctionBegin;
1449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1450   PetscValidType(mat,1);
1451   PetscValidScalarPointer(v,3);
1452   PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow));
1453   PetscCall(MatSetValuesRow(mat,globalrow,v));
1454   PetscFunctionReturn(0);
1455 }
1456 
1457 /*@
1458    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1459         values into a matrix
1460 
1461    Not Collective
1462 
1463    Input Parameters:
1464 +  mat - the matrix
1465 .  row - the (block) row to set
1466 -  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
1467 
1468    Notes:
1469    The values, v, are column-oriented for the block version.
1470 
1471    All the nonzeros in the row must be provided
1472 
1473    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1474 
1475    The row must belong to this process
1476 
1477    Level: advanced
1478 
1479 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`,
1480           `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`
1481 @*/
1482 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1483 {
1484   PetscFunctionBeginHot;
1485   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1486   PetscValidType(mat,1);
1487   MatCheckPreallocated(mat,1);
1488   PetscValidScalarPointer(v,3);
1489   PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1490   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1491   mat->insertmode = INSERT_VALUES;
1492 
1493   if (mat->assembled) {
1494     mat->was_assembled = PETSC_TRUE;
1495     mat->assembled     = PETSC_FALSE;
1496   }
1497   PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0));
1498   PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1499   PetscCall((*mat->ops->setvaluesrow)(mat,row,v));
1500   PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0));
1501   PetscFunctionReturn(0);
1502 }
1503 
1504 /*@
1505    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1506      Using structured grid indexing
1507 
1508    Not Collective
1509 
1510    Input Parameters:
1511 +  mat - the matrix
1512 .  m - number of rows being entered
1513 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1514 .  n - number of columns being entered
1515 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1516 .  v - a logically two-dimensional array of values
1517 -  addv - either ADD_VALUES or INSERT_VALUES, where
1518    ADD_VALUES adds values to any existing entries, and
1519    INSERT_VALUES replaces existing entries with new values
1520 
1521    Notes:
1522    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1523 
1524    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1525    options cannot be mixed without intervening calls to the assembly
1526    routines.
1527 
1528    The grid coordinates are across the entire grid, not just the local portion
1529 
1530    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1531    as well as in C.
1532 
1533    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1534 
1535    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1536    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1537 
1538    The columns and rows in the stencil passed in MUST be contained within the
1539    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1540    if you create a DMDA with an overlap of one grid level and on a particular process its first
1541    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1542    first i index you can use in your column and row indices in MatSetStencil() is 5.
1543 
1544    In Fortran idxm and idxn should be declared as
1545 $     MatStencil idxm(4,m),idxn(4,n)
1546    and the values inserted using
1547 $    idxm(MatStencil_i,1) = i
1548 $    idxm(MatStencil_j,1) = j
1549 $    idxm(MatStencil_k,1) = k
1550 $    idxm(MatStencil_c,1) = c
1551    etc
1552 
1553    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1554    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1555    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1556    DM_BOUNDARY_PERIODIC boundary type.
1557 
1558    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
1559    a single value per point) you can skip filling those indices.
1560 
1561    Inspired by the structured grid interface to the HYPRE package
1562    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1563 
1564    Efficiency Alert:
1565    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1566    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1567 
1568    Level: beginner
1569 
1570 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`
1571           `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`
1572 @*/
1573 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1574 {
1575   PetscInt       buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1576   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1577   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1578 
1579   PetscFunctionBegin;
1580   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1581   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1582   PetscValidType(mat,1);
1583   PetscValidPointer(idxm,3);
1584   PetscValidPointer(idxn,5);
1585 
1586   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1587     jdxm = buf; jdxn = buf+m;
1588   } else {
1589     PetscCall(PetscMalloc2(m,&bufm,n,&bufn));
1590     jdxm = bufm; jdxn = bufn;
1591   }
1592   for (i=0; i<m; i++) {
1593     for (j=0; j<3-sdim; j++) dxm++;
1594     tmp = *dxm++ - starts[0];
1595     for (j=0; j<dim-1; j++) {
1596       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1597       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1598     }
1599     if (mat->stencil.noc) dxm++;
1600     jdxm[i] = tmp;
1601   }
1602   for (i=0; i<n; i++) {
1603     for (j=0; j<3-sdim; j++) dxn++;
1604     tmp = *dxn++ - starts[0];
1605     for (j=0; j<dim-1; j++) {
1606       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1607       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1608     }
1609     if (mat->stencil.noc) dxn++;
1610     jdxn[i] = tmp;
1611   }
1612   PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv));
1613   PetscCall(PetscFree2(bufm,bufn));
1614   PetscFunctionReturn(0);
1615 }
1616 
1617 /*@
1618    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1619      Using structured grid indexing
1620 
1621    Not Collective
1622 
1623    Input Parameters:
1624 +  mat - the matrix
1625 .  m - number of rows being entered
1626 .  idxm - grid coordinates for matrix rows being entered
1627 .  n - number of columns being entered
1628 .  idxn - grid coordinates for matrix columns being entered
1629 .  v - a logically two-dimensional array of values
1630 -  addv - either ADD_VALUES or INSERT_VALUES, where
1631    ADD_VALUES adds values to any existing entries, and
1632    INSERT_VALUES replaces existing entries with new values
1633 
1634    Notes:
1635    By default the values, v, are row-oriented and unsorted.
1636    See MatSetOption() for other options.
1637 
1638    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1639    options cannot be mixed without intervening calls to the assembly
1640    routines.
1641 
1642    The grid coordinates are across the entire grid, not just the local portion
1643 
1644    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1645    as well as in C.
1646 
1647    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1648 
1649    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1650    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1651 
1652    The columns and rows in the stencil passed in MUST be contained within the
1653    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1654    if you create a DMDA with an overlap of one grid level and on a particular process its first
1655    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1656    first i index you can use in your column and row indices in MatSetStencil() is 5.
1657 
1658    In Fortran idxm and idxn should be declared as
1659 $     MatStencil idxm(4,m),idxn(4,n)
1660    and the values inserted using
1661 $    idxm(MatStencil_i,1) = i
1662 $    idxm(MatStencil_j,1) = j
1663 $    idxm(MatStencil_k,1) = k
1664    etc
1665 
1666    Negative indices may be passed in idxm and idxn, these rows and columns are
1667    simply ignored. This allows easily inserting element stiffness matrices
1668    with homogeneous Dirchlet boundary conditions that you don't want represented
1669    in the matrix.
1670 
1671    Inspired by the structured grid interface to the HYPRE package
1672    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1673 
1674    Level: beginner
1675 
1676 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`
1677           `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`,
1678           `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`
1679 @*/
1680 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1681 {
1682   PetscInt       buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1683   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1684   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1685 
1686   PetscFunctionBegin;
1687   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1689   PetscValidType(mat,1);
1690   PetscValidPointer(idxm,3);
1691   PetscValidPointer(idxn,5);
1692   PetscValidScalarPointer(v,6);
1693 
1694   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1695     jdxm = buf; jdxn = buf+m;
1696   } else {
1697     PetscCall(PetscMalloc2(m,&bufm,n,&bufn));
1698     jdxm = bufm; jdxn = bufn;
1699   }
1700   for (i=0; i<m; i++) {
1701     for (j=0; j<3-sdim; j++) dxm++;
1702     tmp = *dxm++ - starts[0];
1703     for (j=0; j<sdim-1; j++) {
1704       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1705       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1706     }
1707     dxm++;
1708     jdxm[i] = tmp;
1709   }
1710   for (i=0; i<n; i++) {
1711     for (j=0; j<3-sdim; j++) dxn++;
1712     tmp = *dxn++ - starts[0];
1713     for (j=0; j<sdim-1; j++) {
1714       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1715       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1716     }
1717     dxn++;
1718     jdxn[i] = tmp;
1719   }
1720   PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv));
1721   PetscCall(PetscFree2(bufm,bufn));
1722   PetscFunctionReturn(0);
1723 }
1724 
1725 /*@
1726    MatSetStencil - Sets the grid information for setting values into a matrix via
1727         MatSetValuesStencil()
1728 
1729    Not Collective
1730 
1731    Input Parameters:
1732 +  mat - the matrix
1733 .  dim - dimension of the grid 1, 2, or 3
1734 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1735 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1736 -  dof - number of degrees of freedom per node
1737 
1738    Inspired by the structured grid interface to the HYPRE package
1739    (www.llnl.gov/CASC/hyper)
1740 
1741    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1742    user.
1743 
1744    Level: beginner
1745 
1746 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`
1747           `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()`
1748 @*/
1749 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1750 {
1751   PetscFunctionBegin;
1752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1753   PetscValidIntPointer(dims,3);
1754   PetscValidIntPointer(starts,4);
1755 
1756   mat->stencil.dim = dim + (dof > 1);
1757   for (PetscInt i=0; i<dim; i++) {
1758     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1759     mat->stencil.starts[i] = starts[dim-i-1];
1760   }
1761   mat->stencil.dims[dim]   = dof;
1762   mat->stencil.starts[dim] = 0;
1763   mat->stencil.noc         = (PetscBool)(dof == 1);
1764   PetscFunctionReturn(0);
1765 }
1766 
1767 /*@C
1768    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1769 
1770    Not Collective
1771 
1772    Input Parameters:
1773 +  mat - the matrix
1774 .  v - a logically two-dimensional array of values
1775 .  m, idxm - the number of block rows and their global block indices
1776 .  n, idxn - the number of block columns and their global block indices
1777 -  addv - either ADD_VALUES or INSERT_VALUES, where
1778    ADD_VALUES adds values to any existing entries, and
1779    INSERT_VALUES replaces existing entries with new values
1780 
1781    Notes:
1782    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1783    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1784 
1785    The m and n count the NUMBER of blocks in the row direction and column direction,
1786    NOT the total number of rows/columns; for example, if the block size is 2 and
1787    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1788    The values in idxm would be 1 2; that is the first index for each block divided by
1789    the block size.
1790 
1791    Note that you must call MatSetBlockSize() when constructing this matrix (before
1792    preallocating it).
1793 
1794    By default the values, v, are row-oriented, so the layout of
1795    v is the same as for MatSetValues(). See MatSetOption() for other options.
1796 
1797    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1798    options cannot be mixed without intervening calls to the assembly
1799    routines.
1800 
1801    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1802    as well as in C.
1803 
1804    Negative indices may be passed in idxm and idxn, these rows and columns are
1805    simply ignored. This allows easily inserting element stiffness matrices
1806    with homogeneous Dirchlet boundary conditions that you don't want represented
1807    in the matrix.
1808 
1809    Each time an entry is set within a sparse matrix via MatSetValues(),
1810    internal searching must be done to determine where to place the
1811    data in the matrix storage space.  By instead inserting blocks of
1812    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1813    reduced.
1814 
1815    Example:
1816 $   Suppose m=n=2 and block size(bs) = 2 The array is
1817 $
1818 $   1  2  | 3  4
1819 $   5  6  | 7  8
1820 $   - - - | - - -
1821 $   9  10 | 11 12
1822 $   13 14 | 15 16
1823 $
1824 $   v[] should be passed in like
1825 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1826 $
1827 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1828 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1829 
1830    Level: intermediate
1831 
1832 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()`
1833 @*/
1834 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1835 {
1836   PetscFunctionBeginHot;
1837   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1838   PetscValidType(mat,1);
1839   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1840   PetscValidIntPointer(idxm,3);
1841   PetscValidIntPointer(idxn,5);
1842   MatCheckPreallocated(mat,1);
1843   if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv;
1844   else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1845   if (PetscDefined(USE_DEBUG)) {
1846     PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1847     PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1848   }
1849   if (PetscDefined(USE_DEBUG)) {
1850     PetscInt rbs,cbs,M,N,i;
1851     PetscCall(MatGetBlockSizes(mat,&rbs,&cbs));
1852     PetscCall(MatGetSize(mat,&M,&N));
1853     for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M);
1854     for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N);
1855   }
1856   if (mat->assembled) {
1857     mat->was_assembled = PETSC_TRUE;
1858     mat->assembled     = PETSC_FALSE;
1859   }
1860   PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0));
1861   if (mat->ops->setvaluesblocked) {
1862     PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv));
1863   } else {
1864     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn;
1865     PetscInt i,j,bs,cbs;
1866 
1867     PetscCall(MatGetBlockSizes(mat,&bs,&cbs));
1868     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1869       iidxm = buf;
1870       iidxn = buf + m*bs;
1871     } else {
1872       PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc));
1873       iidxm = bufr;
1874       iidxn = bufc;
1875     }
1876     for (i=0; i<m; i++) {
1877       for (j=0; j<bs; j++) {
1878         iidxm[i*bs+j] = bs*idxm[i] + j;
1879       }
1880     }
1881     if (m != n || bs != cbs || idxm != idxn) {
1882       for (i=0; i<n; i++) {
1883         for (j=0; j<cbs; j++) {
1884           iidxn[i*cbs+j] = cbs*idxn[i] + j;
1885         }
1886       }
1887     } else iidxn = iidxm;
1888     PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv));
1889     PetscCall(PetscFree2(bufr,bufc));
1890   }
1891   PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0));
1892   PetscFunctionReturn(0);
1893 }
1894 
1895 /*@C
1896    MatGetValues - Gets a block of values from a matrix.
1897 
1898    Not Collective; can only return values that are owned by the give process
1899 
1900    Input Parameters:
1901 +  mat - the matrix
1902 .  v - a logically two-dimensional array for storing the values
1903 .  m, idxm - the number of rows and their global indices
1904 -  n, idxn - the number of columns and their global indices
1905 
1906    Notes:
1907      The user must allocate space (m*n PetscScalars) for the values, v.
1908      The values, v, are then returned in a row-oriented format,
1909      analogous to that used by default in MatSetValues().
1910 
1911      MatGetValues() uses 0-based row and column numbers in
1912      Fortran as well as in C.
1913 
1914      MatGetValues() requires that the matrix has been assembled
1915      with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1916      MatSetValues() and MatGetValues() CANNOT be made in succession
1917      without intermediate matrix assembly.
1918 
1919      Negative row or column indices will be ignored and those locations in v[] will be
1920      left unchanged.
1921 
1922      For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank.
1923      That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable
1924      from MatGetOwnershipRange(mat,&rstart,&rend).
1925 
1926    Level: advanced
1927 
1928 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()`
1929 @*/
1930 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1931 {
1932   PetscFunctionBegin;
1933   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1934   PetscValidType(mat,1);
1935   if (!m || !n) PetscFunctionReturn(0);
1936   PetscValidIntPointer(idxm,3);
1937   PetscValidIntPointer(idxn,5);
1938   PetscValidScalarPointer(v,6);
1939   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1940   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1941   PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1942   MatCheckPreallocated(mat,1);
1943 
1944   PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0));
1945   PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v));
1946   PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0));
1947   PetscFunctionReturn(0);
1948 }
1949 
1950 /*@C
1951    MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices
1952      defined previously by MatSetLocalToGlobalMapping()
1953 
1954    Not Collective
1955 
1956    Input Parameters:
1957 +  mat - the matrix
1958 .  nrow, irow - number of rows and their local indices
1959 -  ncol, icol - number of columns and their local indices
1960 
1961    Output Parameter:
1962 .  y -  a logically two-dimensional array of values
1963 
1964    Notes:
1965      If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine.
1966 
1967      This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering,
1968      are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can
1969      determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set
1970      with MatSetLocalToGlobalMapping().
1971 
1972    Developer Notes:
1973       This is labelled with C so does not automatically generate Fortran stubs and interfaces
1974       because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1975 
1976    Level: advanced
1977 
1978 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`,
1979           `MatSetValuesLocal()`, `MatGetValues()`
1980 @*/
1981 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[])
1982 {
1983   PetscFunctionBeginHot;
1984   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1985   PetscValidType(mat,1);
1986   MatCheckPreallocated(mat,1);
1987   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */
1988   PetscValidIntPointer(irow,3);
1989   PetscValidIntPointer(icol,5);
1990   if (PetscDefined(USE_DEBUG)) {
1991     PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1992     PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1993   }
1994   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1995   PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0));
1996   if (mat->ops->getvalueslocal) {
1997     PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y));
1998   } else {
1999     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2000     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2001       irowm = buf; icolm = buf+nrow;
2002     } else {
2003       PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc));
2004       irowm = bufr; icolm = bufc;
2005     }
2006     PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2007     PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2008     PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm));
2009     PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm));
2010     PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y));
2011     PetscCall(PetscFree2(bufr,bufc));
2012   }
2013   PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0));
2014   PetscFunctionReturn(0);
2015 }
2016 
2017 /*@
2018   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
2019   the same size. Currently, this can only be called once and creates the given matrix.
2020 
2021   Not Collective
2022 
2023   Input Parameters:
2024 + mat - the matrix
2025 . nb - the number of blocks
2026 . bs - the number of rows (and columns) in each block
2027 . rows - a concatenation of the rows for each block
2028 - v - a concatenation of logically two-dimensional arrays of values
2029 
2030   Notes:
2031   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2032 
2033   Level: advanced
2034 
2035 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`,
2036           `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`
2037 @*/
2038 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2039 {
2040   PetscFunctionBegin;
2041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2042   PetscValidType(mat,1);
2043   PetscValidIntPointer(rows,4);
2044   PetscValidScalarPointer(v,5);
2045   PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2046 
2047   PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0));
2048   if (mat->ops->setvaluesbatch) {
2049     PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v));
2050   } else {
2051     for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES));
2052   }
2053   PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0));
2054   PetscFunctionReturn(0);
2055 }
2056 
2057 /*@
2058    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2059    the routine MatSetValuesLocal() to allow users to insert matrix entries
2060    using a local (per-processor) numbering.
2061 
2062    Not Collective
2063 
2064    Input Parameters:
2065 +  x - the matrix
2066 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
2067 -  cmapping - column mapping
2068 
2069    Level: intermediate
2070 
2071 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()`
2072 @*/
2073 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2074 {
2075   PetscFunctionBegin;
2076   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2077   PetscValidType(x,1);
2078   if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2079   if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2080   if (x->ops->setlocaltoglobalmapping) {
2081     PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping));
2082   } else {
2083     PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping));
2084     PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping));
2085   }
2086   PetscFunctionReturn(0);
2087 }
2088 
2089 /*@
2090    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2091 
2092    Not Collective
2093 
2094    Input Parameter:
2095 .  A - the matrix
2096 
2097    Output Parameters:
2098 + rmapping - row mapping
2099 - cmapping - column mapping
2100 
2101    Level: advanced
2102 
2103 .seealso: `MatSetValuesLocal()`
2104 @*/
2105 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2106 {
2107   PetscFunctionBegin;
2108   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2109   PetscValidType(A,1);
2110   if (rmapping) {
2111     PetscValidPointer(rmapping,2);
2112     *rmapping = A->rmap->mapping;
2113   }
2114   if (cmapping) {
2115     PetscValidPointer(cmapping,3);
2116     *cmapping = A->cmap->mapping;
2117   }
2118   PetscFunctionReturn(0);
2119 }
2120 
2121 /*@
2122    MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix
2123 
2124    Logically Collective on A
2125 
2126    Input Parameters:
2127 +  A - the matrix
2128 . rmap - row layout
2129 - cmap - column layout
2130 
2131    Level: advanced
2132 
2133 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()`
2134 @*/
2135 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap)
2136 {
2137   PetscFunctionBegin;
2138   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2139   PetscCall(PetscLayoutReference(rmap,&A->rmap));
2140   PetscCall(PetscLayoutReference(cmap,&A->cmap));
2141   PetscFunctionReturn(0);
2142 }
2143 
2144 /*@
2145    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2146 
2147    Not Collective
2148 
2149    Input Parameter:
2150 .  A - the matrix
2151 
2152    Output Parameters:
2153 + rmap - row layout
2154 - cmap - column layout
2155 
2156    Level: advanced
2157 
2158 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()`
2159 @*/
2160 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2161 {
2162   PetscFunctionBegin;
2163   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2164   PetscValidType(A,1);
2165   if (rmap) {
2166     PetscValidPointer(rmap,2);
2167     *rmap = A->rmap;
2168   }
2169   if (cmap) {
2170     PetscValidPointer(cmap,3);
2171     *cmap = A->cmap;
2172   }
2173   PetscFunctionReturn(0);
2174 }
2175 
2176 /*@C
2177    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2178    using a local numbering of the nodes.
2179 
2180    Not Collective
2181 
2182    Input Parameters:
2183 +  mat - the matrix
2184 .  nrow, irow - number of rows and their local indices
2185 .  ncol, icol - number of columns and their local indices
2186 .  y -  a logically two-dimensional array of values
2187 -  addv - either INSERT_VALUES or ADD_VALUES, where
2188    ADD_VALUES adds values to any existing entries, and
2189    INSERT_VALUES replaces existing entries with new values
2190 
2191    Notes:
2192    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2193       MatSetUp() before using this routine
2194 
2195    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2196 
2197    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2198    options cannot be mixed without intervening calls to the assembly
2199    routines.
2200 
2201    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2202    MUST be called after all calls to MatSetValuesLocal() have been completed.
2203 
2204    Level: intermediate
2205 
2206    Developer Notes:
2207     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2208                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2209 
2210 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`,
2211           `MatSetValueLocal()`, `MatGetValuesLocal()`
2212 @*/
2213 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2214 {
2215   PetscFunctionBeginHot;
2216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2217   PetscValidType(mat,1);
2218   MatCheckPreallocated(mat,1);
2219   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2220   PetscValidIntPointer(irow,3);
2221   PetscValidIntPointer(icol,5);
2222   if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv;
2223   else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2224   if (PetscDefined(USE_DEBUG)) {
2225     PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2226     PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2227   }
2228 
2229   if (mat->assembled) {
2230     mat->was_assembled = PETSC_TRUE;
2231     mat->assembled     = PETSC_FALSE;
2232   }
2233   PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0));
2234   if (mat->ops->setvalueslocal) {
2235     PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv));
2236   } else {
2237     PetscInt       buf[8192],*bufr=NULL,*bufc=NULL;
2238     const PetscInt *irowm,*icolm;
2239 
2240     if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2241       bufr  = buf;
2242       bufc  = buf + nrow;
2243       irowm = bufr;
2244       icolm = bufc;
2245     } else {
2246       PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc));
2247       irowm = bufr;
2248       icolm = bufc;
2249     }
2250     if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr));
2251     else irowm = irow;
2252     if (mat->cmap->mapping) {
2253       if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) {
2254         PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc));
2255       } else icolm = irowm;
2256     } else icolm = icol;
2257     PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv));
2258     if (bufr != buf) PetscCall(PetscFree2(bufr,bufc));
2259   }
2260   PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0));
2261   PetscFunctionReturn(0);
2262 }
2263 
2264 /*@C
2265    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2266    using a local ordering of the nodes a block at a time.
2267 
2268    Not Collective
2269 
2270    Input Parameters:
2271 +  x - the matrix
2272 .  nrow, irow - number of rows and their local indices
2273 .  ncol, icol - number of columns and their local indices
2274 .  y -  a logically two-dimensional array of values
2275 -  addv - either INSERT_VALUES or ADD_VALUES, where
2276    ADD_VALUES adds values to any existing entries, and
2277    INSERT_VALUES replaces existing entries with new values
2278 
2279    Notes:
2280    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2281       MatSetUp() before using this routine
2282 
2283    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2284       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2285 
2286    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2287    options cannot be mixed without intervening calls to the assembly
2288    routines.
2289 
2290    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2291    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2292 
2293    Level: intermediate
2294 
2295    Developer Notes:
2296     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2297                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2298 
2299 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`,
2300           `MatSetValuesLocal()`, `MatSetValuesBlocked()`
2301 @*/
2302 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2303 {
2304   PetscFunctionBeginHot;
2305   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2306   PetscValidType(mat,1);
2307   MatCheckPreallocated(mat,1);
2308   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2309   PetscValidIntPointer(irow,3);
2310   PetscValidIntPointer(icol,5);
2311   if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv;
2312   else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2313   if (PetscDefined(USE_DEBUG)) {
2314     PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2315     PetscCheck(mat->ops->setvaluesblockedlocal || mat->ops->setvaluesblocked || mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2316   }
2317 
2318   if (mat->assembled) {
2319     mat->was_assembled = PETSC_TRUE;
2320     mat->assembled     = PETSC_FALSE;
2321   }
2322   if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2323     PetscInt irbs, rbs;
2324     PetscCall(MatGetBlockSizes(mat, &rbs, NULL));
2325     PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs));
2326     PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs);
2327   }
2328   if (PetscUnlikelyDebug(mat->cmap->mapping)) {
2329     PetscInt icbs, cbs;
2330     PetscCall(MatGetBlockSizes(mat,NULL,&cbs));
2331     PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs));
2332     PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs);
2333   }
2334   PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0));
2335   if (mat->ops->setvaluesblockedlocal) {
2336     PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv));
2337   } else {
2338     PetscInt       buf[8192],*bufr=NULL,*bufc=NULL;
2339     const PetscInt *irowm,*icolm;
2340 
2341     if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2342       bufr  = buf;
2343       bufc  = buf + nrow;
2344       irowm = bufr;
2345       icolm = bufc;
2346     } else {
2347       PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc));
2348       irowm = bufr;
2349       icolm = bufc;
2350     }
2351     if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr));
2352     else irowm = irow;
2353     if (mat->cmap->mapping) {
2354       if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) {
2355         PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc));
2356       } else icolm = irowm;
2357     } else icolm = icol;
2358     PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv));
2359     if (bufr != buf) PetscCall(PetscFree2(bufr,bufc));
2360   }
2361   PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0));
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 /*@
2366    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2367 
2368    Collective on Mat
2369 
2370    Input Parameters:
2371 +  mat - the matrix
2372 -  x   - the vector to be multiplied
2373 
2374    Output Parameters:
2375 .  y - the result
2376 
2377    Notes:
2378    The vectors x and y cannot be the same.  I.e., one cannot
2379    call MatMult(A,y,y).
2380 
2381    Level: developer
2382 
2383 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()`
2384 @*/
2385 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2386 {
2387   PetscFunctionBegin;
2388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2389   PetscValidType(mat,1);
2390   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2391   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2392 
2393   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2394   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2395   PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2396   MatCheckPreallocated(mat,1);
2397 
2398   PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2399   PetscCall((*mat->ops->multdiagonalblock)(mat,x,y));
2400   PetscCall(PetscObjectStateIncrease((PetscObject)y));
2401   PetscFunctionReturn(0);
2402 }
2403 
2404 /* --------------------------------------------------------*/
2405 /*@
2406    MatMult - Computes the matrix-vector product, y = Ax.
2407 
2408    Neighbor-wise Collective on Mat
2409 
2410    Input Parameters:
2411 +  mat - the matrix
2412 -  x   - the vector to be multiplied
2413 
2414    Output Parameters:
2415 .  y - the result
2416 
2417    Notes:
2418    The vectors x and y cannot be the same.  I.e., one cannot
2419    call MatMult(A,y,y).
2420 
2421    Level: beginner
2422 
2423 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()`
2424 @*/
2425 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2426 {
2427   PetscFunctionBegin;
2428   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2429   PetscValidType(mat,1);
2430   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2431   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2432   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2433   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2434   PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2435   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
2436   PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N);
2437   PetscCheck(mat->cmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n);
2438   PetscCheck(mat->rmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n);
2439   PetscCall(VecSetErrorIfLocked(y,3));
2440   if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE));
2441   MatCheckPreallocated(mat,1);
2442 
2443   PetscCall(VecLockReadPush(x));
2444   PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2445   PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0));
2446   PetscCall((*mat->ops->mult)(mat,x,y));
2447   PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0));
2448   if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE));
2449   PetscCall(VecLockReadPop(x));
2450   PetscFunctionReturn(0);
2451 }
2452 
2453 /*@
2454    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2455 
2456    Neighbor-wise Collective on Mat
2457 
2458    Input Parameters:
2459 +  mat - the matrix
2460 -  x   - the vector to be multiplied
2461 
2462    Output Parameters:
2463 .  y - the result
2464 
2465    Notes:
2466    The vectors x and y cannot be the same.  I.e., one cannot
2467    call MatMultTranspose(A,y,y).
2468 
2469    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2470    use MatMultHermitianTranspose()
2471 
2472    Level: beginner
2473 
2474 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()`
2475 @*/
2476 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2477 {
2478   PetscErrorCode (*op)(Mat,Vec,Vec) = NULL;
2479 
2480   PetscFunctionBegin;
2481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2482   PetscValidType(mat,1);
2483   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2484   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2485 
2486   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2487   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2488   PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2489   PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N);
2490   PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N);
2491   PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n);
2492   PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n);
2493   if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE));
2494   MatCheckPreallocated(mat,1);
2495 
2496   if (!mat->ops->multtranspose) {
2497     if (mat->symmetric && mat->ops->mult) op = mat->ops->mult;
2498     PetscCheck(op,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);
2499   } else op = mat->ops->multtranspose;
2500   PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0));
2501   PetscCall(VecLockReadPush(x));
2502   PetscCall((*op)(mat,x,y));
2503   PetscCall(VecLockReadPop(x));
2504   PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0));
2505   PetscCall(PetscObjectStateIncrease((PetscObject)y));
2506   if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE));
2507   PetscFunctionReturn(0);
2508 }
2509 
2510 /*@
2511    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2512 
2513    Neighbor-wise Collective on Mat
2514 
2515    Input Parameters:
2516 +  mat - the matrix
2517 -  x   - the vector to be multilplied
2518 
2519    Output Parameters:
2520 .  y - the result
2521 
2522    Notes:
2523    The vectors x and y cannot be the same.  I.e., one cannot
2524    call MatMultHermitianTranspose(A,y,y).
2525 
2526    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2527 
2528    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2529 
2530    Level: beginner
2531 
2532 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()`
2533 @*/
2534 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2535 {
2536   PetscFunctionBegin;
2537   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2538   PetscValidType(mat,1);
2539   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2540   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2541 
2542   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2543   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2544   PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2545   PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N);
2546   PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N);
2547   PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n);
2548   PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n);
2549   MatCheckPreallocated(mat,1);
2550 
2551   PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0));
2552 #if defined(PETSC_USE_COMPLEX)
2553   if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) {
2554     PetscCall(VecLockReadPush(x));
2555     if (mat->ops->multhermitiantranspose) {
2556       PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y));
2557     } else {
2558       PetscCall((*mat->ops->mult)(mat,x,y));
2559     }
2560     PetscCall(VecLockReadPop(x));
2561   } else {
2562     Vec w;
2563     PetscCall(VecDuplicate(x,&w));
2564     PetscCall(VecCopy(x,w));
2565     PetscCall(VecConjugate(w));
2566     PetscCall(MatMultTranspose(mat,w,y));
2567     PetscCall(VecDestroy(&w));
2568     PetscCall(VecConjugate(y));
2569   }
2570   PetscCall(PetscObjectStateIncrease((PetscObject)y));
2571 #else
2572   PetscCall(MatMultTranspose(mat,x,y));
2573 #endif
2574   PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0));
2575   PetscFunctionReturn(0);
2576 }
2577 
2578 /*@
2579     MatMultAdd -  Computes v3 = v2 + A * v1.
2580 
2581     Neighbor-wise Collective on Mat
2582 
2583     Input Parameters:
2584 +   mat - the matrix
2585 -   v1, v2 - the vectors
2586 
2587     Output Parameters:
2588 .   v3 - the result
2589 
2590     Notes:
2591     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2592     call MatMultAdd(A,v1,v2,v1).
2593 
2594     Level: beginner
2595 
2596 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()`
2597 @*/
2598 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2599 {
2600   PetscFunctionBegin;
2601   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2602   PetscValidType(mat,1);
2603   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2604   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2605   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2606 
2607   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2608   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2609   PetscCheck(mat->cmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N);
2610   /* PetscCheck(mat->rmap->N == v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N);
2611      PetscCheck(mat->rmap->N == v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */
2612   PetscCheck(mat->rmap->n == v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n);
2613   PetscCheck(mat->rmap->n == v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n);
2614   PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2615   MatCheckPreallocated(mat,1);
2616 
2617   PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name);
2618   PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3));
2619   PetscCall(VecLockReadPush(v1));
2620   PetscCall((*mat->ops->multadd)(mat,v1,v2,v3));
2621   PetscCall(VecLockReadPop(v1));
2622   PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3));
2623   PetscCall(PetscObjectStateIncrease((PetscObject)v3));
2624   PetscFunctionReturn(0);
2625 }
2626 
2627 /*@
2628    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2629 
2630    Neighbor-wise Collective on Mat
2631 
2632    Input Parameters:
2633 +  mat - the matrix
2634 -  v1, v2 - the vectors
2635 
2636    Output Parameters:
2637 .  v3 - the result
2638 
2639    Notes:
2640    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2641    call MatMultTransposeAdd(A,v1,v2,v1).
2642 
2643    Level: beginner
2644 
2645 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()`
2646 @*/
2647 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2648 {
2649   PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd;
2650 
2651   PetscFunctionBegin;
2652   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2653   PetscValidType(mat,1);
2654   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2655   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2656   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2657 
2658   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2659   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2660   PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N);
2661   PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N);
2662   PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N);
2663   PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2664   PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2665   MatCheckPreallocated(mat,1);
2666 
2667   PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3));
2668   PetscCall(VecLockReadPush(v1));
2669   PetscCall((*op)(mat,v1,v2,v3));
2670   PetscCall(VecLockReadPop(v1));
2671   PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3));
2672   PetscCall(PetscObjectStateIncrease((PetscObject)v3));
2673   PetscFunctionReturn(0);
2674 }
2675 
2676 /*@
2677    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2678 
2679    Neighbor-wise Collective on Mat
2680 
2681    Input Parameters:
2682 +  mat - the matrix
2683 -  v1, v2 - the vectors
2684 
2685    Output Parameters:
2686 .  v3 - the result
2687 
2688    Notes:
2689    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2690    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2691 
2692    Level: beginner
2693 
2694 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()`
2695 @*/
2696 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2697 {
2698   PetscFunctionBegin;
2699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2700   PetscValidType(mat,1);
2701   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2702   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2703   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2704 
2705   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2706   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2707   PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2708   PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N);
2709   PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N);
2710   PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N);
2711   MatCheckPreallocated(mat,1);
2712 
2713   PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3));
2714   PetscCall(VecLockReadPush(v1));
2715   if (mat->ops->multhermitiantransposeadd) {
2716     PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3));
2717   } else {
2718     Vec w,z;
2719     PetscCall(VecDuplicate(v1,&w));
2720     PetscCall(VecCopy(v1,w));
2721     PetscCall(VecConjugate(w));
2722     PetscCall(VecDuplicate(v3,&z));
2723     PetscCall(MatMultTranspose(mat,w,z));
2724     PetscCall(VecDestroy(&w));
2725     PetscCall(VecConjugate(z));
2726     if (v2 != v3) {
2727       PetscCall(VecWAXPY(v3,1.0,v2,z));
2728     } else {
2729       PetscCall(VecAXPY(v3,1.0,z));
2730     }
2731     PetscCall(VecDestroy(&z));
2732   }
2733   PetscCall(VecLockReadPop(v1));
2734   PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3));
2735   PetscCall(PetscObjectStateIncrease((PetscObject)v3));
2736   PetscFunctionReturn(0);
2737 }
2738 
2739 /*@C
2740    MatGetFactorType - gets the type of factorization it is
2741 
2742    Not Collective
2743 
2744    Input Parameters:
2745 .  mat - the matrix
2746 
2747    Output Parameters:
2748 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2749 
2750    Level: intermediate
2751 
2752 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()`
2753 @*/
2754 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2755 {
2756   PetscFunctionBegin;
2757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2758   PetscValidType(mat,1);
2759   PetscValidPointer(t,2);
2760   *t = mat->factortype;
2761   PetscFunctionReturn(0);
2762 }
2763 
2764 /*@C
2765    MatSetFactorType - sets the type of factorization it is
2766 
2767    Logically Collective on Mat
2768 
2769    Input Parameters:
2770 +  mat - the matrix
2771 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2772 
2773    Level: intermediate
2774 
2775 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()`
2776 @*/
2777 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2778 {
2779   PetscFunctionBegin;
2780   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2781   PetscValidType(mat,1);
2782   mat->factortype = t;
2783   PetscFunctionReturn(0);
2784 }
2785 
2786 /* ------------------------------------------------------------*/
2787 /*@C
2788    MatGetInfo - Returns information about matrix storage (number of
2789    nonzeros, memory, etc.).
2790 
2791    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2792 
2793    Input Parameter:
2794 .  mat - the matrix
2795 
2796    Output Parameters:
2797 +  flag - flag indicating the type of parameters to be returned
2798    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2799    MAT_GLOBAL_SUM - sum over all processors)
2800 -  info - matrix information context
2801 
2802    Notes:
2803    The MatInfo context contains a variety of matrix data, including
2804    number of nonzeros allocated and used, number of mallocs during
2805    matrix assembly, etc.  Additional information for factored matrices
2806    is provided (such as the fill ratio, number of mallocs during
2807    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2808    when using the runtime options
2809 $       -info -mat_view ::ascii_info
2810 
2811    Example for C/C++ Users:
2812    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2813    data within the MatInfo context.  For example,
2814 .vb
2815       MatInfo info;
2816       Mat     A;
2817       double  mal, nz_a, nz_u;
2818 
2819       MatGetInfo(A,MAT_LOCAL,&info);
2820       mal  = info.mallocs;
2821       nz_a = info.nz_allocated;
2822 .ve
2823 
2824    Example for Fortran Users:
2825    Fortran users should declare info as a double precision
2826    array of dimension MAT_INFO_SIZE, and then extract the parameters
2827    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2828    a complete list of parameter names.
2829 .vb
2830       double  precision info(MAT_INFO_SIZE)
2831       double  precision mal, nz_a
2832       Mat     A
2833       integer ierr
2834 
2835       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2836       mal = info(MAT_INFO_MALLOCS)
2837       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2838 .ve
2839 
2840     Level: intermediate
2841 
2842     Developer Note: fortran interface is not autogenerated as the f90
2843     interface definition cannot be generated correctly [due to MatInfo]
2844 
2845 .seealso: `MatStashGetInfo()`
2846 
2847 @*/
2848 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2849 {
2850   PetscFunctionBegin;
2851   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2852   PetscValidType(mat,1);
2853   PetscValidPointer(info,3);
2854   PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2855   MatCheckPreallocated(mat,1);
2856   PetscCall((*mat->ops->getinfo)(mat,flag,info));
2857   PetscFunctionReturn(0);
2858 }
2859 
2860 /*
2861    This is used by external packages where it is not easy to get the info from the actual
2862    matrix factorization.
2863 */
2864 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2865 {
2866   PetscFunctionBegin;
2867   PetscCall(PetscMemzero(info,sizeof(MatInfo)));
2868   PetscFunctionReturn(0);
2869 }
2870 
2871 /* ----------------------------------------------------------*/
2872 
2873 /*@C
2874    MatLUFactor - Performs in-place LU factorization of matrix.
2875 
2876    Collective on Mat
2877 
2878    Input Parameters:
2879 +  mat - the matrix
2880 .  row - row permutation
2881 .  col - column permutation
2882 -  info - options for factorization, includes
2883 $          fill - expected fill as ratio of original fill.
2884 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2885 $                   Run with the option -info to determine an optimal value to use
2886 
2887    Notes:
2888    Most users should employ the simplified KSP interface for linear solvers
2889    instead of working directly with matrix algebra routines such as this.
2890    See, e.g., KSPCreate().
2891 
2892    This changes the state of the matrix to a factored matrix; it cannot be used
2893    for example with MatSetValues() unless one first calls MatSetUnfactored().
2894 
2895    Level: developer
2896 
2897 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`,
2898           `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()`
2899 
2900     Developer Note: fortran interface is not autogenerated as the f90
2901     interface definition cannot be generated correctly [due to MatFactorInfo]
2902 
2903 @*/
2904 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2905 {
2906   MatFactorInfo  tinfo;
2907 
2908   PetscFunctionBegin;
2909   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2910   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2911   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2912   if (info) PetscValidPointer(info,4);
2913   PetscValidType(mat,1);
2914   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2915   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2916   PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2917   MatCheckPreallocated(mat,1);
2918   if (!info) {
2919     PetscCall(MatFactorInfoInitialize(&tinfo));
2920     info = &tinfo;
2921   }
2922 
2923   PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0));
2924   PetscCall((*mat->ops->lufactor)(mat,row,col,info));
2925   PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0));
2926   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
2927   PetscFunctionReturn(0);
2928 }
2929 
2930 /*@C
2931    MatILUFactor - Performs in-place ILU factorization of matrix.
2932 
2933    Collective on Mat
2934 
2935    Input Parameters:
2936 +  mat - the matrix
2937 .  row - row permutation
2938 .  col - column permutation
2939 -  info - structure containing
2940 $      levels - number of levels of fill.
2941 $      expected fill - as ratio of original fill.
2942 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2943                 missing diagonal entries)
2944 
2945    Notes:
2946    Probably really in-place only when level of fill is zero, otherwise allocates
2947    new space to store factored matrix and deletes previous memory.
2948 
2949    Most users should employ the simplified KSP interface for linear solvers
2950    instead of working directly with matrix algebra routines such as this.
2951    See, e.g., KSPCreate().
2952 
2953    Level: developer
2954 
2955 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`
2956 
2957     Developer Note: fortran interface is not autogenerated as the f90
2958     interface definition cannot be generated correctly [due to MatFactorInfo]
2959 
2960 @*/
2961 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2962 {
2963   PetscFunctionBegin;
2964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2965   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2966   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2967   PetscValidPointer(info,4);
2968   PetscValidType(mat,1);
2969   PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2970   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2971   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2972   PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2973   MatCheckPreallocated(mat,1);
2974 
2975   PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0));
2976   PetscCall((*mat->ops->ilufactor)(mat,row,col,info));
2977   PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0));
2978   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
2979   PetscFunctionReturn(0);
2980 }
2981 
2982 /*@C
2983    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2984    Call this routine before calling MatLUFactorNumeric().
2985 
2986    Collective on Mat
2987 
2988    Input Parameters:
2989 +  fact - the factor matrix obtained with MatGetFactor()
2990 .  mat - the matrix
2991 .  row, col - row and column permutations
2992 -  info - options for factorization, includes
2993 $          fill - expected fill as ratio of original fill.
2994 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2995 $                   Run with the option -info to determine an optimal value to use
2996 
2997    Notes:
2998     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2999 
3000    Most users should employ the simplified KSP interface for linear solvers
3001    instead of working directly with matrix algebra routines such as this.
3002    See, e.g., KSPCreate().
3003 
3004    Level: developer
3005 
3006 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()`
3007 
3008     Developer Note: fortran interface is not autogenerated as the f90
3009     interface definition cannot be generated correctly [due to MatFactorInfo]
3010 
3011 @*/
3012 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3013 {
3014   MatFactorInfo  tinfo;
3015 
3016   PetscFunctionBegin;
3017   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3018   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3);
3019   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4);
3020   if (info) PetscValidPointer(info,5);
3021   PetscValidType(mat,2);
3022   PetscValidPointer(fact,1);
3023   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3024   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3025   if (!(fact)->ops->lufactorsymbolic) {
3026     MatSolverType stype;
3027     PetscCall(MatFactorGetSolverType(fact,&stype));
3028     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype);
3029   }
3030   MatCheckPreallocated(mat,2);
3031   if (!info) {
3032     PetscCall(MatFactorInfoInitialize(&tinfo));
3033     info = &tinfo;
3034   }
3035 
3036   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0));
3037   PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info));
3038   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0));
3039   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3040   PetscFunctionReturn(0);
3041 }
3042 
3043 /*@C
3044    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3045    Call this routine after first calling MatLUFactorSymbolic().
3046 
3047    Collective on Mat
3048 
3049    Input Parameters:
3050 +  fact - the factor matrix obtained with MatGetFactor()
3051 .  mat - the matrix
3052 -  info - options for factorization
3053 
3054    Notes:
3055    See MatLUFactor() for in-place factorization.  See
3056    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3057 
3058    Most users should employ the simplified KSP interface for linear solvers
3059    instead of working directly with matrix algebra routines such as this.
3060    See, e.g., KSPCreate().
3061 
3062    Level: developer
3063 
3064 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()`
3065 
3066     Developer Note: fortran interface is not autogenerated as the f90
3067     interface definition cannot be generated correctly [due to MatFactorInfo]
3068 
3069 @*/
3070 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3071 {
3072   MatFactorInfo  tinfo;
3073 
3074   PetscFunctionBegin;
3075   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3076   PetscValidType(mat,2);
3077   PetscValidPointer(fact,1);
3078   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3079   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3080   PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3081 
3082   PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3083   MatCheckPreallocated(mat,2);
3084   if (!info) {
3085     PetscCall(MatFactorInfoInitialize(&tinfo));
3086     info = &tinfo;
3087   }
3088 
3089   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0));
3090   else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0));
3091   PetscCall((fact->ops->lufactornumeric)(fact,mat,info));
3092   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0));
3093   else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0));
3094   PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view"));
3095   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3096   PetscFunctionReturn(0);
3097 }
3098 
3099 /*@C
3100    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3101    symmetric matrix.
3102 
3103    Collective on Mat
3104 
3105    Input Parameters:
3106 +  mat - the matrix
3107 .  perm - row and column permutations
3108 -  f - expected fill as ratio of original fill
3109 
3110    Notes:
3111    See MatLUFactor() for the nonsymmetric case.  See also
3112    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3113 
3114    Most users should employ the simplified KSP interface for linear solvers
3115    instead of working directly with matrix algebra routines such as this.
3116    See, e.g., KSPCreate().
3117 
3118    Level: developer
3119 
3120 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()`
3121           `MatGetOrdering()`
3122 
3123     Developer Note: fortran interface is not autogenerated as the f90
3124     interface definition cannot be generated correctly [due to MatFactorInfo]
3125 
3126 @*/
3127 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3128 {
3129   MatFactorInfo  tinfo;
3130 
3131   PetscFunctionBegin;
3132   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3133   PetscValidType(mat,1);
3134   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3135   if (info) PetscValidPointer(info,3);
3136   PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3137   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3138   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3139   PetscCheck(mat->ops->choleskyfactor,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);
3140   MatCheckPreallocated(mat,1);
3141   if (!info) {
3142     PetscCall(MatFactorInfoInitialize(&tinfo));
3143     info = &tinfo;
3144   }
3145 
3146   PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0));
3147   PetscCall((*mat->ops->choleskyfactor)(mat,perm,info));
3148   PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0));
3149   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
3150   PetscFunctionReturn(0);
3151 }
3152 
3153 /*@C
3154    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3155    of a symmetric matrix.
3156 
3157    Collective on Mat
3158 
3159    Input Parameters:
3160 +  fact - the factor matrix obtained with MatGetFactor()
3161 .  mat - the matrix
3162 .  perm - row and column permutations
3163 -  info - options for factorization, includes
3164 $          fill - expected fill as ratio of original fill.
3165 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3166 $                   Run with the option -info to determine an optimal value to use
3167 
3168    Notes:
3169    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3170    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3171 
3172    Most users should employ the simplified KSP interface for linear solvers
3173    instead of working directly with matrix algebra routines such as this.
3174    See, e.g., KSPCreate().
3175 
3176    Level: developer
3177 
3178 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()`
3179           `MatGetOrdering()`
3180 
3181     Developer Note: fortran interface is not autogenerated as the f90
3182     interface definition cannot be generated correctly [due to MatFactorInfo]
3183 
3184 @*/
3185 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3186 {
3187   MatFactorInfo  tinfo;
3188 
3189   PetscFunctionBegin;
3190   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3191   PetscValidType(mat,2);
3192   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3);
3193   if (info) PetscValidPointer(info,4);
3194   PetscValidPointer(fact,1);
3195   PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3196   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3197   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3198   if (!(fact)->ops->choleskyfactorsymbolic) {
3199     MatSolverType stype;
3200     PetscCall(MatFactorGetSolverType(fact,&stype));
3201     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype);
3202   }
3203   MatCheckPreallocated(mat,2);
3204   if (!info) {
3205     PetscCall(MatFactorInfoInitialize(&tinfo));
3206     info = &tinfo;
3207   }
3208 
3209   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0));
3210   PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info));
3211   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0));
3212   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3213   PetscFunctionReturn(0);
3214 }
3215 
3216 /*@C
3217    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3218    of a symmetric matrix. Call this routine after first calling
3219    MatCholeskyFactorSymbolic().
3220 
3221    Collective on Mat
3222 
3223    Input Parameters:
3224 +  fact - the factor matrix obtained with MatGetFactor()
3225 .  mat - the initial matrix
3226 .  info - options for factorization
3227 -  fact - the symbolic factor of mat
3228 
3229    Notes:
3230    Most users should employ the simplified KSP interface for linear solvers
3231    instead of working directly with matrix algebra routines such as this.
3232    See, e.g., KSPCreate().
3233 
3234    Level: developer
3235 
3236 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()`
3237 
3238     Developer Note: fortran interface is not autogenerated as the f90
3239     interface definition cannot be generated correctly [due to MatFactorInfo]
3240 
3241 @*/
3242 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3243 {
3244   MatFactorInfo  tinfo;
3245 
3246   PetscFunctionBegin;
3247   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3248   PetscValidType(mat,2);
3249   PetscValidPointer(fact,1);
3250   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3251   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3252   PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3253   PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3254   MatCheckPreallocated(mat,2);
3255   if (!info) {
3256     PetscCall(MatFactorInfoInitialize(&tinfo));
3257     info = &tinfo;
3258   }
3259 
3260   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0));
3261   else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0));
3262   PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info));
3263   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0));
3264   else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0));
3265   PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view"));
3266   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3267   PetscFunctionReturn(0);
3268 }
3269 
3270 /*@
3271    MatQRFactor - Performs in-place QR factorization of matrix.
3272 
3273    Collective on Mat
3274 
3275    Input Parameters:
3276 +  mat - the matrix
3277 .  col - column permutation
3278 -  info - options for factorization, includes
3279 $          fill - expected fill as ratio of original fill.
3280 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3281 $                   Run with the option -info to determine an optimal value to use
3282 
3283    Notes:
3284    Most users should employ the simplified KSP interface for linear solvers
3285    instead of working directly with matrix algebra routines such as this.
3286    See, e.g., KSPCreate().
3287 
3288    This changes the state of the matrix to a factored matrix; it cannot be used
3289    for example with MatSetValues() unless one first calls MatSetUnfactored().
3290 
3291    Level: developer
3292 
3293 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`,
3294           `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()`
3295 
3296     Developer Note: fortran interface is not autogenerated as the f90
3297     interface definition cannot be generated correctly [due to MatFactorInfo]
3298 
3299 @*/
3300 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info)
3301 {
3302   PetscFunctionBegin;
3303   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3304   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2);
3305   if (info) PetscValidPointer(info,3);
3306   PetscValidType(mat,1);
3307   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3308   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3309   MatCheckPreallocated(mat,1);
3310   PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0));
3311   PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info));
3312   PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0));
3313   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
3314   PetscFunctionReturn(0);
3315 }
3316 
3317 /*@
3318    MatQRFactorSymbolic - Performs symbolic QR factorization of matrix.
3319    Call this routine before calling MatQRFactorNumeric().
3320 
3321    Collective on Mat
3322 
3323    Input Parameters:
3324 +  fact - the factor matrix obtained with MatGetFactor()
3325 .  mat - the matrix
3326 .  col - column permutation
3327 -  info - options for factorization, includes
3328 $          fill - expected fill as ratio of original fill.
3329 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3330 $                   Run with the option -info to determine an optimal value to use
3331 
3332    Most users should employ the simplified KSP interface for linear solvers
3333    instead of working directly with matrix algebra routines such as this.
3334    See, e.g., KSPCreate().
3335 
3336    Level: developer
3337 
3338 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()`
3339 
3340     Developer Note: fortran interface is not autogenerated as the f90
3341     interface definition cannot be generated correctly [due to MatFactorInfo]
3342 
3343 @*/
3344 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info)
3345 {
3346   MatFactorInfo  tinfo;
3347 
3348   PetscFunctionBegin;
3349   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3350   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3351   if (info) PetscValidPointer(info,4);
3352   PetscValidType(mat,2);
3353   PetscValidPointer(fact,1);
3354   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3355   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3356   MatCheckPreallocated(mat,2);
3357   if (!info) {
3358     PetscCall(MatFactorInfoInitialize(&tinfo));
3359     info = &tinfo;
3360   }
3361 
3362   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0));
3363   PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info));
3364   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0));
3365   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3366   PetscFunctionReturn(0);
3367 }
3368 
3369 /*@
3370    MatQRFactorNumeric - Performs numeric QR factorization of a matrix.
3371    Call this routine after first calling MatQRFactorSymbolic().
3372 
3373    Collective on Mat
3374 
3375    Input Parameters:
3376 +  fact - the factor matrix obtained with MatGetFactor()
3377 .  mat - the matrix
3378 -  info - options for factorization
3379 
3380    Notes:
3381    See MatQRFactor() for in-place factorization.
3382 
3383    Most users should employ the simplified KSP interface for linear solvers
3384    instead of working directly with matrix algebra routines such as this.
3385    See, e.g., KSPCreate().
3386 
3387    Level: developer
3388 
3389 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()`
3390 
3391     Developer Note: fortran interface is not autogenerated as the f90
3392     interface definition cannot be generated correctly [due to MatFactorInfo]
3393 
3394 @*/
3395 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3396 {
3397   MatFactorInfo  tinfo;
3398 
3399   PetscFunctionBegin;
3400   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3401   PetscValidType(mat,2);
3402   PetscValidPointer(fact,1);
3403   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3404   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3405   PetscCheck(mat->rmap->N == fact->rmap->N && mat->cmap->N == fact->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3406 
3407   MatCheckPreallocated(mat,2);
3408   if (!info) {
3409     PetscCall(MatFactorInfoInitialize(&tinfo));
3410     info = &tinfo;
3411   }
3412 
3413   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0));
3414   else  PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0));
3415   PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info));
3416   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0));
3417   else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0));
3418   PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view"));
3419   PetscCall(PetscObjectStateIncrease((PetscObject)fact));
3420   PetscFunctionReturn(0);
3421 }
3422 
3423 /* ----------------------------------------------------------------*/
3424 /*@
3425    MatSolve - Solves A x = b, given a factored matrix.
3426 
3427    Neighbor-wise Collective on Mat
3428 
3429    Input Parameters:
3430 +  mat - the factored matrix
3431 -  b - the right-hand-side vector
3432 
3433    Output Parameter:
3434 .  x - the result vector
3435 
3436    Notes:
3437    The vectors b and x cannot be the same.  I.e., one cannot
3438    call MatSolve(A,x,x).
3439 
3440    Notes:
3441    Most users should employ the simplified KSP interface for linear solvers
3442    instead of working directly with matrix algebra routines such as this.
3443    See, e.g., KSPCreate().
3444 
3445    Level: developer
3446 
3447 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`
3448 @*/
3449 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3450 {
3451   PetscFunctionBegin;
3452   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3453   PetscValidType(mat,1);
3454   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3455   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3456   PetscCheckSameComm(mat,1,b,2);
3457   PetscCheckSameComm(mat,1,x,3);
3458   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3459   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
3460   PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N);
3461   PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n);
3462   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3463   MatCheckPreallocated(mat,1);
3464 
3465   PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0));
3466   if (mat->factorerrortype) {
3467     PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype));
3468     PetscCall(VecSetInf(x));
3469   } else {
3470     PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3471     PetscCall((*mat->ops->solve)(mat,b,x));
3472   }
3473   PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0));
3474   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3475   PetscFunctionReturn(0);
3476 }
3477 
3478 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3479 {
3480   Vec            b,x;
3481   PetscInt       N,i;
3482   PetscErrorCode (*f)(Mat,Vec,Vec);
3483   PetscBool      Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE;
3484 
3485   PetscFunctionBegin;
3486   if (A->factorerrortype) {
3487     PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype));
3488     PetscCall(MatSetInf(X));
3489     PetscFunctionReturn(0);
3490   }
3491   f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose;
3492   PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3493   PetscCall(MatBoundToCPU(A,&Abound));
3494   if (!Abound) {
3495     PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,""));
3496     PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,""));
3497   }
3498   if (Bneedconv) {
3499     PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B));
3500   }
3501   if (Xneedconv) {
3502     PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X));
3503   }
3504   PetscCall(MatGetSize(B,NULL,&N));
3505   for (i=0; i<N; i++) {
3506     PetscCall(MatDenseGetColumnVecRead(B,i,&b));
3507     PetscCall(MatDenseGetColumnVecWrite(X,i,&x));
3508     PetscCall((*f)(A,b,x));
3509     PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x));
3510     PetscCall(MatDenseRestoreColumnVecRead(B,i,&b));
3511   }
3512   if (Bneedconv) {
3513     PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B));
3514   }
3515   if (Xneedconv) {
3516     PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X));
3517   }
3518   PetscFunctionReturn(0);
3519 }
3520 
3521 /*@
3522    MatMatSolve - Solves A X = B, given a factored matrix.
3523 
3524    Neighbor-wise Collective on Mat
3525 
3526    Input Parameters:
3527 +  A - the factored matrix
3528 -  B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3529 
3530    Output Parameter:
3531 .  X - the result matrix (dense matrix)
3532 
3533    Notes:
3534    If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO;
3535    otherwise, B and X cannot be the same.
3536 
3537    Notes:
3538    Most users should usually employ the simplified KSP interface for linear solvers
3539    instead of working directly with matrix algebra routines such as this.
3540    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3541    at a time.
3542 
3543    Level: developer
3544 
3545 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()`
3546 @*/
3547 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3548 {
3549   PetscFunctionBegin;
3550   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3551   PetscValidType(A,1);
3552   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3553   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3554   PetscCheckSameComm(A,1,B,2);
3555   PetscCheckSameComm(A,1,X,3);
3556   PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N);
3557   PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N);
3558   PetscCheck(X->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3559   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3560   PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3561   MatCheckPreallocated(A,1);
3562 
3563   PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0));
3564   if (!A->ops->matsolve) {
3565     PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name));
3566     PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE));
3567   } else {
3568     PetscCall((*A->ops->matsolve)(A,B,X));
3569   }
3570   PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0));
3571   PetscCall(PetscObjectStateIncrease((PetscObject)X));
3572   PetscFunctionReturn(0);
3573 }
3574 
3575 /*@
3576    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3577 
3578    Neighbor-wise Collective on Mat
3579 
3580    Input Parameters:
3581 +  A - the factored matrix
3582 -  B - the right-hand-side matrix  (dense matrix)
3583 
3584    Output Parameter:
3585 .  X - the result matrix (dense matrix)
3586 
3587    Notes:
3588    The matrices B and X cannot be the same.  I.e., one cannot
3589    call MatMatSolveTranspose(A,X,X).
3590 
3591    Notes:
3592    Most users should usually employ the simplified KSP interface for linear solvers
3593    instead of working directly with matrix algebra routines such as this.
3594    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3595    at a time.
3596 
3597    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3598 
3599    Level: developer
3600 
3601 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()`
3602 @*/
3603 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3604 {
3605   PetscFunctionBegin;
3606   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3607   PetscValidType(A,1);
3608   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3609   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3610   PetscCheckSameComm(A,1,B,2);
3611   PetscCheckSameComm(A,1,X,3);
3612   PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3613   PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N);
3614   PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N);
3615   PetscCheck(A->rmap->n == B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n);
3616   PetscCheck(X->cmap->N >= B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3617   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3618   PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3619   MatCheckPreallocated(A,1);
3620 
3621   PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0));
3622   if (!A->ops->matsolvetranspose) {
3623     PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name));
3624     PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE));
3625   } else {
3626     PetscCall((*A->ops->matsolvetranspose)(A,B,X));
3627   }
3628   PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0));
3629   PetscCall(PetscObjectStateIncrease((PetscObject)X));
3630   PetscFunctionReturn(0);
3631 }
3632 
3633 /*@
3634    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3635 
3636    Neighbor-wise Collective on Mat
3637 
3638    Input Parameters:
3639 +  A - the factored matrix
3640 -  Bt - the transpose of right-hand-side matrix
3641 
3642    Output Parameter:
3643 .  X - the result matrix (dense matrix)
3644 
3645    Notes:
3646    Most users should usually employ the simplified KSP interface for linear solvers
3647    instead of working directly with matrix algebra routines such as this.
3648    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3649    at a time.
3650 
3651    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().
3652 
3653    Level: developer
3654 
3655 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()`
3656 @*/
3657 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3658 {
3659   PetscFunctionBegin;
3660   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3661   PetscValidType(A,1);
3662   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3663   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3664   PetscCheckSameComm(A,1,Bt,2);
3665   PetscCheckSameComm(A,1,X,3);
3666 
3667   PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3668   PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N);
3669   PetscCheck(A->rmap->N == Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N);
3670   PetscCheck(X->cmap->N >= Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3671   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3672   PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3673   MatCheckPreallocated(A,1);
3674 
3675   PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3676   PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0));
3677   PetscCall((*A->ops->mattransposesolve)(A,Bt,X));
3678   PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0));
3679   PetscCall(PetscObjectStateIncrease((PetscObject)X));
3680   PetscFunctionReturn(0);
3681 }
3682 
3683 /*@
3684    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3685                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3686 
3687    Neighbor-wise Collective on Mat
3688 
3689    Input Parameters:
3690 +  mat - the factored matrix
3691 -  b - the right-hand-side vector
3692 
3693    Output Parameter:
3694 .  x - the result vector
3695 
3696    Notes:
3697    MatSolve() should be used for most applications, as it performs
3698    a forward solve followed by a backward solve.
3699 
3700    The vectors b and x cannot be the same,  i.e., one cannot
3701    call MatForwardSolve(A,x,x).
3702 
3703    For matrix in seqsbaij format with block size larger than 1,
3704    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3705    MatForwardSolve() solves U^T*D y = b, and
3706    MatBackwardSolve() solves U x = y.
3707    Thus they do not provide a symmetric preconditioner.
3708 
3709    Most users should employ the simplified KSP interface for linear solvers
3710    instead of working directly with matrix algebra routines such as this.
3711    See, e.g., KSPCreate().
3712 
3713    Level: developer
3714 
3715 .seealso: `MatSolve()`, `MatBackwardSolve()`
3716 @*/
3717 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3718 {
3719   PetscFunctionBegin;
3720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3721   PetscValidType(mat,1);
3722   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3723   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3724   PetscCheckSameComm(mat,1,b,2);
3725   PetscCheckSameComm(mat,1,x,3);
3726   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3727   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
3728   PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N);
3729   PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n);
3730   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3731   MatCheckPreallocated(mat,1);
3732 
3733   PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3734   PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0));
3735   PetscCall((*mat->ops->forwardsolve)(mat,b,x));
3736   PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0));
3737   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3738   PetscFunctionReturn(0);
3739 }
3740 
3741 /*@
3742    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3743                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3744 
3745    Neighbor-wise Collective on Mat
3746 
3747    Input Parameters:
3748 +  mat - the factored matrix
3749 -  b - the right-hand-side vector
3750 
3751    Output Parameter:
3752 .  x - the result vector
3753 
3754    Notes:
3755    MatSolve() should be used for most applications, as it performs
3756    a forward solve followed by a backward solve.
3757 
3758    The vectors b and x cannot be the same.  I.e., one cannot
3759    call MatBackwardSolve(A,x,x).
3760 
3761    For matrix in seqsbaij format with block size larger than 1,
3762    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3763    MatForwardSolve() solves U^T*D y = b, and
3764    MatBackwardSolve() solves U x = y.
3765    Thus they do not provide a symmetric preconditioner.
3766 
3767    Most users should employ the simplified KSP interface for linear solvers
3768    instead of working directly with matrix algebra routines such as this.
3769    See, e.g., KSPCreate().
3770 
3771    Level: developer
3772 
3773 .seealso: `MatSolve()`, `MatForwardSolve()`
3774 @*/
3775 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3776 {
3777   PetscFunctionBegin;
3778   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3779   PetscValidType(mat,1);
3780   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3781   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3782   PetscCheckSameComm(mat,1,b,2);
3783   PetscCheckSameComm(mat,1,x,3);
3784   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3785   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
3786   PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N);
3787   PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n);
3788   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3789   MatCheckPreallocated(mat,1);
3790 
3791   PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3792   PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0));
3793   PetscCall((*mat->ops->backwardsolve)(mat,b,x));
3794   PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0));
3795   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3796   PetscFunctionReturn(0);
3797 }
3798 
3799 /*@
3800    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3801 
3802    Neighbor-wise Collective on Mat
3803 
3804    Input Parameters:
3805 +  mat - the factored matrix
3806 .  b - the right-hand-side vector
3807 -  y - the vector to be added to
3808 
3809    Output Parameter:
3810 .  x - the result vector
3811 
3812    Notes:
3813    The vectors b and x cannot be the same.  I.e., one cannot
3814    call MatSolveAdd(A,x,y,x).
3815 
3816    Most users should employ the simplified KSP interface for linear solvers
3817    instead of working directly with matrix algebra routines such as this.
3818    See, e.g., KSPCreate().
3819 
3820    Level: developer
3821 
3822 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`
3823 @*/
3824 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3825 {
3826   PetscScalar    one = 1.0;
3827   Vec            tmp;
3828 
3829   PetscFunctionBegin;
3830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3831   PetscValidType(mat,1);
3832   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3833   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3834   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3835   PetscCheckSameComm(mat,1,b,2);
3836   PetscCheckSameComm(mat,1,y,3);
3837   PetscCheckSameComm(mat,1,x,4);
3838   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3839   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
3840   PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N);
3841   PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N);
3842   PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n);
3843   PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n);
3844   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3845    MatCheckPreallocated(mat,1);
3846 
3847   PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y));
3848   if (mat->factorerrortype) {
3849 
3850     PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype));
3851     PetscCall(VecSetInf(x));
3852   } else if (mat->ops->solveadd) {
3853     PetscCall((*mat->ops->solveadd)(mat,b,y,x));
3854   } else {
3855     /* do the solve then the add manually */
3856     if (x != y) {
3857       PetscCall(MatSolve(mat,b,x));
3858       PetscCall(VecAXPY(x,one,y));
3859     } else {
3860       PetscCall(VecDuplicate(x,&tmp));
3861       PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp));
3862       PetscCall(VecCopy(x,tmp));
3863       PetscCall(MatSolve(mat,b,x));
3864       PetscCall(VecAXPY(x,one,tmp));
3865       PetscCall(VecDestroy(&tmp));
3866     }
3867   }
3868   PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y));
3869   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3870   PetscFunctionReturn(0);
3871 }
3872 
3873 /*@
3874    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3875 
3876    Neighbor-wise Collective on Mat
3877 
3878    Input Parameters:
3879 +  mat - the factored matrix
3880 -  b - the right-hand-side vector
3881 
3882    Output Parameter:
3883 .  x - the result vector
3884 
3885    Notes:
3886    The vectors b and x cannot be the same.  I.e., one cannot
3887    call MatSolveTranspose(A,x,x).
3888 
3889    Most users should employ the simplified KSP interface for linear solvers
3890    instead of working directly with matrix algebra routines such as this.
3891    See, e.g., KSPCreate().
3892 
3893    Level: developer
3894 
3895 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()`
3896 @*/
3897 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3898 {
3899   PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose;
3900 
3901   PetscFunctionBegin;
3902   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3903   PetscValidType(mat,1);
3904   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3905   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3906   PetscCheckSameComm(mat,1,b,2);
3907   PetscCheckSameComm(mat,1,x,3);
3908   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3909   PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N);
3910   PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N);
3911   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3912   MatCheckPreallocated(mat,1);
3913   PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0));
3914   if (mat->factorerrortype) {
3915     PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype));
3916     PetscCall(VecSetInf(x));
3917   } else {
3918     PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3919     PetscCall((*f)(mat,b,x));
3920   }
3921   PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0));
3922   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3923   PetscFunctionReturn(0);
3924 }
3925 
3926 /*@
3927    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3928                       factored matrix.
3929 
3930    Neighbor-wise Collective on Mat
3931 
3932    Input Parameters:
3933 +  mat - the factored matrix
3934 .  b - the right-hand-side vector
3935 -  y - the vector to be added to
3936 
3937    Output Parameter:
3938 .  x - the result vector
3939 
3940    Notes:
3941    The vectors b and x cannot be the same.  I.e., one cannot
3942    call MatSolveTransposeAdd(A,x,y,x).
3943 
3944    Most users should employ the simplified KSP interface for linear solvers
3945    instead of working directly with matrix algebra routines such as this.
3946    See, e.g., KSPCreate().
3947 
3948    Level: developer
3949 
3950 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()`
3951 @*/
3952 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3953 {
3954   PetscScalar    one = 1.0;
3955   Vec            tmp;
3956   PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd;
3957 
3958   PetscFunctionBegin;
3959   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3960   PetscValidType(mat,1);
3961   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3962   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3963   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3964   PetscCheckSameComm(mat,1,b,2);
3965   PetscCheckSameComm(mat,1,y,3);
3966   PetscCheckSameComm(mat,1,x,4);
3967   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3968   PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N);
3969   PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N);
3970   PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N);
3971   PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n);
3972   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3973   MatCheckPreallocated(mat,1);
3974 
3975   PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y));
3976   if (mat->factorerrortype) {
3977     PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype));
3978     PetscCall(VecSetInf(x));
3979   } else if (f) {
3980     PetscCall((*f)(mat,b,y,x));
3981   } else {
3982     /* do the solve then the add manually */
3983     if (x != y) {
3984       PetscCall(MatSolveTranspose(mat,b,x));
3985       PetscCall(VecAXPY(x,one,y));
3986     } else {
3987       PetscCall(VecDuplicate(x,&tmp));
3988       PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp));
3989       PetscCall(VecCopy(x,tmp));
3990       PetscCall(MatSolveTranspose(mat,b,x));
3991       PetscCall(VecAXPY(x,one,tmp));
3992       PetscCall(VecDestroy(&tmp));
3993     }
3994   }
3995   PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y));
3996   PetscCall(PetscObjectStateIncrease((PetscObject)x));
3997   PetscFunctionReturn(0);
3998 }
3999 /* ----------------------------------------------------------------*/
4000 
4001 /*@
4002    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
4003 
4004    Neighbor-wise Collective on Mat
4005 
4006    Input Parameters:
4007 +  mat - the matrix
4008 .  b - the right hand side
4009 .  omega - the relaxation factor
4010 .  flag - flag indicating the type of SOR (see below)
4011 .  shift -  diagonal shift
4012 .  its - the number of iterations
4013 -  lits - the number of local iterations
4014 
4015    Output Parameter:
4016 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
4017 
4018    SOR Flags:
4019 +     SOR_FORWARD_SWEEP - forward SOR
4020 .     SOR_BACKWARD_SWEEP - backward SOR
4021 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
4022 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
4023 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
4024 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
4025 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
4026          upper/lower triangular part of matrix to
4027          vector (with omega)
4028 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
4029 
4030    Notes:
4031    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
4032    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
4033    on each processor.
4034 
4035    Application programmers will not generally use MatSOR() directly,
4036    but instead will employ the KSP/PC interface.
4037 
4038    Notes:
4039     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
4040 
4041    Notes for Advanced Users:
4042    The flags are implemented as bitwise inclusive or operations.
4043    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
4044    to specify a zero initial guess for SSOR.
4045 
4046    Most users should employ the simplified KSP interface for linear solvers
4047    instead of working directly with matrix algebra routines such as this.
4048    See, e.g., KSPCreate().
4049 
4050    Vectors x and b CANNOT be the same
4051 
4052    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4053 
4054    Level: developer
4055 
4056 @*/
4057 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4058 {
4059   PetscFunctionBegin;
4060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4061   PetscValidType(mat,1);
4062   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4063   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4064   PetscCheckSameComm(mat,1,b,2);
4065   PetscCheckSameComm(mat,1,x,8);
4066   PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4067   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4068   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4069   PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N);
4070   PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N);
4071   PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n);
4072   PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its);
4073   PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits);
4074   PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4075 
4076   MatCheckPreallocated(mat,1);
4077   PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0));
4078   PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x));
4079   PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0));
4080   PetscCall(PetscObjectStateIncrease((PetscObject)x));
4081   PetscFunctionReturn(0);
4082 }
4083 
4084 /*
4085       Default matrix copy routine.
4086 */
4087 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4088 {
4089   PetscInt          i,rstart = 0,rend = 0,nz;
4090   const PetscInt    *cwork;
4091   const PetscScalar *vwork;
4092 
4093   PetscFunctionBegin;
4094   if (B->assembled) {
4095     PetscCall(MatZeroEntries(B));
4096   }
4097   if (str == SAME_NONZERO_PATTERN) {
4098     PetscCall(MatGetOwnershipRange(A,&rstart,&rend));
4099     for (i=rstart; i<rend; i++) {
4100       PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork));
4101       PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES));
4102       PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork));
4103     }
4104   } else {
4105     PetscCall(MatAYPX(B,0.0,A,str));
4106   }
4107   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
4108   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
4109   PetscFunctionReturn(0);
4110 }
4111 
4112 /*@
4113    MatCopy - Copies a matrix to another matrix.
4114 
4115    Collective on Mat
4116 
4117    Input Parameters:
4118 +  A - the matrix
4119 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4120 
4121    Output Parameter:
4122 .  B - where the copy is put
4123 
4124    Notes:
4125    If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash.
4126 
4127    MatCopy() copies the matrix entries of a matrix to another existing
4128    matrix (after first zeroing the second matrix).  A related routine is
4129    MatConvert(), which first creates a new matrix and then copies the data.
4130 
4131    Level: intermediate
4132 
4133 .seealso: `MatConvert()`, `MatDuplicate()`
4134 @*/
4135 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4136 {
4137   PetscInt       i;
4138 
4139   PetscFunctionBegin;
4140   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4141   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4142   PetscValidType(A,1);
4143   PetscValidType(B,2);
4144   PetscCheckSameComm(A,1,B,2);
4145   MatCheckPreallocated(B,2);
4146   PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4147   PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4148   PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4149   MatCheckPreallocated(A,1);
4150   if (A == B) PetscFunctionReturn(0);
4151 
4152   PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0));
4153   if (A->ops->copy) {
4154     PetscCall((*A->ops->copy)(A,B,str));
4155   } else { /* generic conversion */
4156     PetscCall(MatCopy_Basic(A,B,str));
4157   }
4158 
4159   B->stencil.dim = A->stencil.dim;
4160   B->stencil.noc = A->stencil.noc;
4161   for (i=0; i<=A->stencil.dim; i++) {
4162     B->stencil.dims[i]   = A->stencil.dims[i];
4163     B->stencil.starts[i] = A->stencil.starts[i];
4164   }
4165 
4166   PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0));
4167   PetscCall(PetscObjectStateIncrease((PetscObject)B));
4168   PetscFunctionReturn(0);
4169 }
4170 
4171 /*@C
4172    MatConvert - Converts a matrix to another matrix, either of the same
4173    or different type.
4174 
4175    Collective on Mat
4176 
4177    Input Parameters:
4178 +  mat - the matrix
4179 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4180    same type as the original matrix.
4181 -  reuse - denotes if the destination matrix is to be created or reused.
4182    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
4183    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).
4184 
4185    Output Parameter:
4186 .  M - pointer to place new matrix
4187 
4188    Notes:
4189    MatConvert() first creates a new matrix and then copies the data from
4190    the first matrix.  A related routine is MatCopy(), which copies the matrix
4191    entries of one matrix to another already existing matrix context.
4192 
4193    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4194    the MPI communicator of the generated matrix is always the same as the communicator
4195    of the input matrix.
4196 
4197    Level: intermediate
4198 
4199 .seealso: `MatCopy()`, `MatDuplicate()`
4200 @*/
4201 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M)
4202 {
4203   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4204   char           convname[256],mtype[256];
4205   Mat            B;
4206 
4207   PetscFunctionBegin;
4208   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4209   PetscValidType(mat,1);
4210   PetscValidPointer(M,4);
4211   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4212   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4213   MatCheckPreallocated(mat,1);
4214 
4215   PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg));
4216   if (flg) newtype = mtype;
4217 
4218   PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype));
4219   PetscCall(PetscStrcmp(newtype,"same",&issame));
4220   PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4221   PetscCheck(!(reuse == MAT_REUSE_MATRIX) || !(mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4222 
4223   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4224     PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame));
4225     PetscFunctionReturn(0);
4226   }
4227 
4228   /* Cache Mat options because some converter use MatHeaderReplace  */
4229   issymmetric = mat->symmetric;
4230   ishermitian = mat->hermitian;
4231 
4232   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4233     PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame));
4234     PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M));
4235   } else {
4236     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4237     const char     *prefix[3] = {"seq","mpi",""};
4238     PetscInt       i;
4239     /*
4240        Order of precedence:
4241        0) See if newtype is a superclass of the current matrix.
4242        1) See if a specialized converter is known to the current matrix.
4243        2) See if a specialized converter is known to the desired matrix class.
4244        3) See if a good general converter is registered for the desired class
4245           (as of 6/27/03 only MATMPIADJ falls into this category).
4246        4) See if a good general converter is known for the current matrix.
4247        5) Use a really basic converter.
4248     */
4249 
4250     /* 0) See if newtype is a superclass of the current matrix.
4251           i.e mat is mpiaij and newtype is aij */
4252     for (i=0; i<2; i++) {
4253       PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname)));
4254       PetscCall(PetscStrlcat(convname,newtype,sizeof(convname)));
4255       PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg));
4256       PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg));
4257       if (flg) {
4258         if (reuse == MAT_INPLACE_MATRIX) {
4259           PetscCall(PetscInfo(mat,"Early return\n"));
4260           PetscFunctionReturn(0);
4261         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4262           PetscCall(PetscInfo(mat,"Calling MatDuplicate\n"));
4263           PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M));
4264           PetscFunctionReturn(0);
4265         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4266           PetscCall(PetscInfo(mat,"Calling MatCopy\n"));
4267           PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN));
4268           PetscFunctionReturn(0);
4269         }
4270       }
4271     }
4272     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4273     for (i=0; i<3; i++) {
4274       PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname)));
4275       PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname)));
4276       PetscCall(PetscStrlcat(convname,"_",sizeof(convname)));
4277       PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname)));
4278       PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname)));
4279       PetscCall(PetscStrlcat(convname,"_C",sizeof(convname)));
4280       PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv));
4281       PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv));
4282       if (conv) goto foundconv;
4283     }
4284 
4285     /* 2)  See if a specialized converter is known to the desired matrix class. */
4286     PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B));
4287     PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N));
4288     PetscCall(MatSetType(B,newtype));
4289     for (i=0; i<3; i++) {
4290       PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname)));
4291       PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname)));
4292       PetscCall(PetscStrlcat(convname,"_",sizeof(convname)));
4293       PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname)));
4294       PetscCall(PetscStrlcat(convname,newtype,sizeof(convname)));
4295       PetscCall(PetscStrlcat(convname,"_C",sizeof(convname)));
4296       PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv));
4297       PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv));
4298       if (conv) {
4299         PetscCall(MatDestroy(&B));
4300         goto foundconv;
4301       }
4302     }
4303 
4304     /* 3) See if a good general converter is registered for the desired class */
4305     conv = B->ops->convertfrom;
4306     PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv));
4307     PetscCall(MatDestroy(&B));
4308     if (conv) goto foundconv;
4309 
4310     /* 4) See if a good general converter is known for the current matrix */
4311     if (mat->ops->convert) conv = mat->ops->convert;
4312     PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv));
4313     if (conv) goto foundconv;
4314 
4315     /* 5) Use a really basic converter. */
4316     PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n"));
4317     conv = MatConvert_Basic;
4318 
4319 foundconv:
4320     PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0));
4321     PetscCall((*conv)(mat,newtype,reuse,M));
4322     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4323       /* the block sizes must be same if the mappings are copied over */
4324       (*M)->rmap->bs = mat->rmap->bs;
4325       (*M)->cmap->bs = mat->cmap->bs;
4326       PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping));
4327       PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping));
4328       (*M)->rmap->mapping = mat->rmap->mapping;
4329       (*M)->cmap->mapping = mat->cmap->mapping;
4330     }
4331     (*M)->stencil.dim = mat->stencil.dim;
4332     (*M)->stencil.noc = mat->stencil.noc;
4333     for (i=0; i<=mat->stencil.dim; i++) {
4334       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4335       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4336     }
4337     PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0));
4338   }
4339   PetscCall(PetscObjectStateIncrease((PetscObject)*M));
4340 
4341   /* Copy Mat options */
4342   if (issymmetric) {
4343     PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE));
4344   }
4345   if (ishermitian) {
4346     PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE));
4347   }
4348   PetscFunctionReturn(0);
4349 }
4350 
4351 /*@C
4352    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4353 
4354    Not Collective
4355 
4356    Input Parameter:
4357 .  mat - the matrix, must be a factored matrix
4358 
4359    Output Parameter:
4360 .   type - the string name of the package (do not free this string)
4361 
4362    Notes:
4363       In Fortran you pass in a empty string and the package name will be copied into it.
4364     (Make sure the string is long enough)
4365 
4366    Level: intermediate
4367 
4368 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`
4369 @*/
4370 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4371 {
4372   PetscErrorCode (*conv)(Mat,MatSolverType*);
4373 
4374   PetscFunctionBegin;
4375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4376   PetscValidType(mat,1);
4377   PetscValidPointer(type,2);
4378   PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4379   PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv));
4380   if (conv) PetscCall((*conv)(mat,type));
4381   else *type = MATSOLVERPETSC;
4382   PetscFunctionReturn(0);
4383 }
4384 
4385 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4386 struct _MatSolverTypeForSpecifcType {
4387   MatType                        mtype;
4388   /* no entry for MAT_FACTOR_NONE */
4389   PetscErrorCode                 (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*);
4390   MatSolverTypeForSpecifcType next;
4391 };
4392 
4393 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4394 struct _MatSolverTypeHolder {
4395   char                        *name;
4396   MatSolverTypeForSpecifcType handlers;
4397   MatSolverTypeHolder         next;
4398 };
4399 
4400 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4401 
4402 /*@C
4403    MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type
4404 
4405    Input Parameters:
4406 +    package - name of the package, for example petsc or superlu
4407 .    mtype - the matrix type that works with this package
4408 .    ftype - the type of factorization supported by the package
4409 -    createfactor - routine that will create the factored matrix ready to be used
4410 
4411     Level: intermediate
4412 
4413 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`
4414 @*/
4415 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*))
4416 {
4417   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4418   PetscBool                   flg;
4419   MatSolverTypeForSpecifcType inext,iprev = NULL;
4420 
4421   PetscFunctionBegin;
4422   PetscCall(MatInitializePackage());
4423   if (!next) {
4424     PetscCall(PetscNew(&MatSolverTypeHolders));
4425     PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name));
4426     PetscCall(PetscNew(&MatSolverTypeHolders->handlers));
4427     PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype));
4428     MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor;
4429     PetscFunctionReturn(0);
4430   }
4431   while (next) {
4432     PetscCall(PetscStrcasecmp(package,next->name,&flg));
4433     if (flg) {
4434       PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4435       inext = next->handlers;
4436       while (inext) {
4437         PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg));
4438         if (flg) {
4439           inext->createfactor[(int)ftype-1] = createfactor;
4440           PetscFunctionReturn(0);
4441         }
4442         iprev = inext;
4443         inext = inext->next;
4444       }
4445       PetscCall(PetscNew(&iprev->next));
4446       PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype));
4447       iprev->next->createfactor[(int)ftype-1] = createfactor;
4448       PetscFunctionReturn(0);
4449     }
4450     prev = next;
4451     next = next->next;
4452   }
4453   PetscCall(PetscNew(&prev->next));
4454   PetscCall(PetscStrallocpy(package,&prev->next->name));
4455   PetscCall(PetscNew(&prev->next->handlers));
4456   PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype));
4457   prev->next->handlers->createfactor[(int)ftype-1] = createfactor;
4458   PetscFunctionReturn(0);
4459 }
4460 
4461 /*@C
4462    MatSolverTypeGet - Gets the function that creates the factor matrix if it exist
4463 
4464    Input Parameters:
4465 +    type - name of the package, for example petsc or superlu
4466 .    ftype - the type of factorization supported by the type
4467 -    mtype - the matrix type that works with this type
4468 
4469    Output Parameters:
4470 +   foundtype - PETSC_TRUE if the type was registered
4471 .   foundmtype - PETSC_TRUE if the type supports the requested mtype
4472 -   createfactor - routine that will create the factored matrix ready to be used or NULL if not found
4473 
4474     Level: intermediate
4475 
4476 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()`
4477 @*/
4478 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*))
4479 {
4480   MatSolverTypeHolder         next = MatSolverTypeHolders;
4481   PetscBool                   flg;
4482   MatSolverTypeForSpecifcType inext;
4483 
4484   PetscFunctionBegin;
4485   if (foundtype) *foundtype = PETSC_FALSE;
4486   if (foundmtype) *foundmtype = PETSC_FALSE;
4487   if (createfactor) *createfactor = NULL;
4488 
4489   if (type) {
4490     while (next) {
4491       PetscCall(PetscStrcasecmp(type,next->name,&flg));
4492       if (flg) {
4493         if (foundtype) *foundtype = PETSC_TRUE;
4494         inext = next->handlers;
4495         while (inext) {
4496           PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg));
4497           if (flg) {
4498             if (foundmtype) *foundmtype = PETSC_TRUE;
4499             if (createfactor)  *createfactor  = inext->createfactor[(int)ftype-1];
4500             PetscFunctionReturn(0);
4501           }
4502           inext = inext->next;
4503         }
4504       }
4505       next = next->next;
4506     }
4507   } else {
4508     while (next) {
4509       inext = next->handlers;
4510       while (inext) {
4511         PetscCall(PetscStrcmp(mtype,inext->mtype,&flg));
4512         if (flg && inext->createfactor[(int)ftype-1]) {
4513           if (foundtype) *foundtype = PETSC_TRUE;
4514           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4515           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4516           PetscFunctionReturn(0);
4517         }
4518         inext = inext->next;
4519       }
4520       next = next->next;
4521     }
4522     /* try with base classes inext->mtype */
4523     next = MatSolverTypeHolders;
4524     while (next) {
4525       inext = next->handlers;
4526       while (inext) {
4527         PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg));
4528         if (flg && inext->createfactor[(int)ftype-1]) {
4529           if (foundtype) *foundtype = PETSC_TRUE;
4530           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4531           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4532           PetscFunctionReturn(0);
4533         }
4534         inext = inext->next;
4535       }
4536       next = next->next;
4537     }
4538   }
4539   PetscFunctionReturn(0);
4540 }
4541 
4542 PetscErrorCode MatSolverTypeDestroy(void)
4543 {
4544   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4545   MatSolverTypeForSpecifcType inext,iprev;
4546 
4547   PetscFunctionBegin;
4548   while (next) {
4549     PetscCall(PetscFree(next->name));
4550     inext = next->handlers;
4551     while (inext) {
4552       PetscCall(PetscFree(inext->mtype));
4553       iprev = inext;
4554       inext = inext->next;
4555       PetscCall(PetscFree(iprev));
4556     }
4557     prev = next;
4558     next = next->next;
4559     PetscCall(PetscFree(prev));
4560   }
4561   MatSolverTypeHolders = NULL;
4562   PetscFunctionReturn(0);
4563 }
4564 
4565 /*@C
4566    MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4567 
4568    Logically Collective on Mat
4569 
4570    Input Parameters:
4571 .  mat - the matrix
4572 
4573    Output Parameters:
4574 .  flg - PETSC_TRUE if uses the ordering
4575 
4576    Notes:
4577       Most internal PETSc factorizations use the ordering passed to the factorization routine but external
4578       packages do not, thus we want to skip generating the ordering when it is not needed or used.
4579 
4580    Level: developer
4581 
4582 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`
4583 @*/
4584 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg)
4585 {
4586   PetscFunctionBegin;
4587   *flg = mat->canuseordering;
4588   PetscFunctionReturn(0);
4589 }
4590 
4591 /*@C
4592    MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object
4593 
4594    Logically Collective on Mat
4595 
4596    Input Parameters:
4597 .  mat - the matrix
4598 
4599    Output Parameters:
4600 .  otype - the preferred type
4601 
4602    Level: developer
4603 
4604 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`
4605 @*/
4606 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype)
4607 {
4608   PetscFunctionBegin;
4609   *otype = mat->preferredordering[ftype];
4610   PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering");
4611   PetscFunctionReturn(0);
4612 }
4613 
4614 /*@C
4615    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4616 
4617    Collective on Mat
4618 
4619    Input Parameters:
4620 +  mat - the matrix
4621 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4622 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4623 
4624    Output Parameters:
4625 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4626 
4627    Notes:
4628       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4629      such as pastix, superlu, mumps etc.
4630 
4631       PETSc must have been ./configure to use the external solver, using the option --download-package
4632 
4633    Developer Notes:
4634       This should actually be called MatCreateFactor() since it creates a new factor object
4635 
4636    Level: intermediate
4637 
4638 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()`
4639 @*/
4640 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4641 {
4642   PetscBool      foundtype,foundmtype;
4643   PetscErrorCode (*conv)(Mat,MatFactorType,Mat*);
4644 
4645   PetscFunctionBegin;
4646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4647   PetscValidType(mat,1);
4648 
4649   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4650   MatCheckPreallocated(mat,1);
4651 
4652   PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv));
4653   if (!foundtype) {
4654     if (type) {
4655       SETERRQ(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);
4656     } else {
4657       SETERRQ(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);
4658     }
4659   }
4660   PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4661   PetscCheck(conv,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);
4662 
4663   PetscCall((*conv)(mat,ftype,f));
4664   PetscFunctionReturn(0);
4665 }
4666 
4667 /*@C
4668    MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type
4669 
4670    Not Collective
4671 
4672    Input Parameters:
4673 +  mat - the matrix
4674 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4675 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4676 
4677    Output Parameter:
4678 .    flg - PETSC_TRUE if the factorization is available
4679 
4680    Notes:
4681       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4682      such as pastix, superlu, mumps etc.
4683 
4684       PETSc must have been ./configure to use the external solver, using the option --download-package
4685 
4686    Developer Notes:
4687       This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object
4688 
4689    Level: intermediate
4690 
4691 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()`
4692 @*/
4693 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4694 {
4695   PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*);
4696 
4697   PetscFunctionBegin;
4698   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4699   PetscValidType(mat,1);
4700   PetscValidBoolPointer(flg,4);
4701 
4702   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4703   MatCheckPreallocated(mat,1);
4704 
4705   PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv));
4706   *flg = gconv ? PETSC_TRUE : PETSC_FALSE;
4707   PetscFunctionReturn(0);
4708 }
4709 
4710 /*@
4711    MatDuplicate - Duplicates a matrix including the non-zero structure.
4712 
4713    Collective on Mat
4714 
4715    Input Parameters:
4716 +  mat - the matrix
4717 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4718         See the manual page for MatDuplicateOption for an explanation of these options.
4719 
4720    Output Parameter:
4721 .  M - pointer to place new matrix
4722 
4723    Level: intermediate
4724 
4725    Notes:
4726     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4727     May be called with an unassembled input Mat if MAT_DO_NOT_COPY_VALUES is used, in which case the output Mat is unassembled as well.
4728     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.
4729 
4730 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption`
4731 @*/
4732 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4733 {
4734   Mat            B;
4735   VecType        vtype;
4736   PetscInt       i;
4737   PetscObject    dm;
4738   void           (*viewf)(void);
4739 
4740   PetscFunctionBegin;
4741   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4742   PetscValidType(mat,1);
4743   PetscValidPointer(M,3);
4744   PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4745   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4746   MatCheckPreallocated(mat,1);
4747 
4748   *M = NULL;
4749   PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name);
4750   PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0));
4751   PetscCall((*mat->ops->duplicate)(mat,op,M));
4752   PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0));
4753   B    = *M;
4754 
4755   PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf));
4756   if (viewf) {
4757     PetscCall(MatSetOperation(B,MATOP_VIEW,viewf));
4758   }
4759   PetscCall(MatGetVecType(mat,&vtype));
4760   PetscCall(MatSetVecType(B,vtype));
4761 
4762   B->stencil.dim = mat->stencil.dim;
4763   B->stencil.noc = mat->stencil.noc;
4764   for (i=0; i<=mat->stencil.dim; i++) {
4765     B->stencil.dims[i]   = mat->stencil.dims[i];
4766     B->stencil.starts[i] = mat->stencil.starts[i];
4767   }
4768 
4769   B->nooffproczerorows = mat->nooffproczerorows;
4770   B->nooffprocentries  = mat->nooffprocentries;
4771 
4772   PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm));
4773   if (dm) {
4774     PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm));
4775   }
4776   PetscCall(PetscObjectStateIncrease((PetscObject)B));
4777   PetscFunctionReturn(0);
4778 }
4779 
4780 /*@
4781    MatGetDiagonal - Gets the diagonal of a matrix.
4782 
4783    Logically Collective on Mat
4784 
4785    Input Parameters:
4786 +  mat - the matrix
4787 -  v - the vector for storing the diagonal
4788 
4789    Output Parameter:
4790 .  v - the diagonal of the matrix
4791 
4792    Level: intermediate
4793 
4794    Note:
4795    Currently only correct in parallel for square matrices.
4796 
4797 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`
4798 @*/
4799 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4800 {
4801   PetscFunctionBegin;
4802   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4803   PetscValidType(mat,1);
4804   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4805   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4806   PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4807   MatCheckPreallocated(mat,1);
4808 
4809   PetscCall((*mat->ops->getdiagonal)(mat,v));
4810   PetscCall(PetscObjectStateIncrease((PetscObject)v));
4811   PetscFunctionReturn(0);
4812 }
4813 
4814 /*@C
4815    MatGetRowMin - Gets the minimum value (of the real part) of each
4816         row of the matrix
4817 
4818    Logically Collective on Mat
4819 
4820    Input Parameter:
4821 .  mat - the matrix
4822 
4823    Output Parameters:
4824 +  v - the vector for storing the maximums
4825 -  idx - the indices of the column found for each row (optional)
4826 
4827    Level: intermediate
4828 
4829    Notes:
4830     The result of this call are the same as if one converted the matrix to dense format
4831       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4832 
4833     This code is only implemented for a couple of matrix formats.
4834 
4835 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`,
4836           `MatGetRowMax()`
4837 @*/
4838 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4839 {
4840   PetscFunctionBegin;
4841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4842   PetscValidType(mat,1);
4843   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4844   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4845 
4846   if (!mat->cmap->N) {
4847     PetscCall(VecSet(v,PETSC_MAX_REAL));
4848     if (idx) {
4849       PetscInt i,m = mat->rmap->n;
4850       for (i=0; i<m; i++) idx[i] = -1;
4851     }
4852   } else {
4853     PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4854     MatCheckPreallocated(mat,1);
4855   }
4856   PetscCall((*mat->ops->getrowmin)(mat,v,idx));
4857   PetscCall(PetscObjectStateIncrease((PetscObject)v));
4858   PetscFunctionReturn(0);
4859 }
4860 
4861 /*@C
4862    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4863         row of the matrix
4864 
4865    Logically Collective on Mat
4866 
4867    Input Parameter:
4868 .  mat - the matrix
4869 
4870    Output Parameters:
4871 +  v - the vector for storing the minimums
4872 -  idx - the indices of the column found for each row (or NULL if not needed)
4873 
4874    Level: intermediate
4875 
4876    Notes:
4877     if a row is completely empty or has only 0.0 values then the idx[] value for that
4878     row is 0 (the first column).
4879 
4880     This code is only implemented for a couple of matrix formats.
4881 
4882 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()`
4883 @*/
4884 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4885 {
4886   PetscFunctionBegin;
4887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4888   PetscValidType(mat,1);
4889   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4890   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4891   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4892 
4893   if (!mat->cmap->N) {
4894     PetscCall(VecSet(v,0.0));
4895     if (idx) {
4896       PetscInt i,m = mat->rmap->n;
4897       for (i=0; i<m; i++) idx[i] = -1;
4898     }
4899   } else {
4900     PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4901     MatCheckPreallocated(mat,1);
4902     if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n));
4903     PetscCall((*mat->ops->getrowminabs)(mat,v,idx));
4904   }
4905   PetscCall(PetscObjectStateIncrease((PetscObject)v));
4906   PetscFunctionReturn(0);
4907 }
4908 
4909 /*@C
4910    MatGetRowMax - Gets the maximum value (of the real part) of each
4911         row of the matrix
4912 
4913    Logically Collective on Mat
4914 
4915    Input Parameter:
4916 .  mat - the matrix
4917 
4918    Output Parameters:
4919 +  v - the vector for storing the maximums
4920 -  idx - the indices of the column found for each row (optional)
4921 
4922    Level: intermediate
4923 
4924    Notes:
4925     The result of this call are the same as if one converted the matrix to dense format
4926       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4927 
4928     This code is only implemented for a couple of matrix formats.
4929 
4930 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()`
4931 @*/
4932 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4933 {
4934   PetscFunctionBegin;
4935   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4936   PetscValidType(mat,1);
4937   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4938   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4939 
4940   if (!mat->cmap->N) {
4941     PetscCall(VecSet(v,PETSC_MIN_REAL));
4942     if (idx) {
4943       PetscInt i,m = mat->rmap->n;
4944       for (i=0; i<m; i++) idx[i] = -1;
4945     }
4946   } else {
4947     PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4948     MatCheckPreallocated(mat,1);
4949     PetscCall((*mat->ops->getrowmax)(mat,v,idx));
4950   }
4951   PetscCall(PetscObjectStateIncrease((PetscObject)v));
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 /*@C
4956    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4957         row of the matrix
4958 
4959    Logically Collective on Mat
4960 
4961    Input Parameter:
4962 .  mat - the matrix
4963 
4964    Output Parameters:
4965 +  v - the vector for storing the maximums
4966 -  idx - the indices of the column found for each row (or NULL if not needed)
4967 
4968    Level: intermediate
4969 
4970    Notes:
4971     if a row is completely empty or has only 0.0 values then the idx[] value for that
4972     row is 0 (the first column).
4973 
4974     This code is only implemented for a couple of matrix formats.
4975 
4976 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`
4977 @*/
4978 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4979 {
4980   PetscFunctionBegin;
4981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4982   PetscValidType(mat,1);
4983   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4984   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4985 
4986   if (!mat->cmap->N) {
4987     PetscCall(VecSet(v,0.0));
4988     if (idx) {
4989       PetscInt i,m = mat->rmap->n;
4990       for (i=0; i<m; i++) idx[i] = -1;
4991     }
4992   } else {
4993     PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4994     MatCheckPreallocated(mat,1);
4995     if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n));
4996     PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx));
4997   }
4998   PetscCall(PetscObjectStateIncrease((PetscObject)v));
4999   PetscFunctionReturn(0);
5000 }
5001 
5002 /*@
5003    MatGetRowSum - Gets the sum of each row of the matrix
5004 
5005    Logically or Neighborhood Collective on Mat
5006 
5007    Input Parameters:
5008 .  mat - the matrix
5009 
5010    Output Parameter:
5011 .  v - the vector for storing the sum of rows
5012 
5013    Level: intermediate
5014 
5015    Notes:
5016     This code is slow since it is not currently specialized for different formats
5017 
5018 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`
5019 @*/
5020 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
5021 {
5022   Vec            ones;
5023 
5024   PetscFunctionBegin;
5025   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5026   PetscValidType(mat,1);
5027   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5028   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5029   MatCheckPreallocated(mat,1);
5030   PetscCall(MatCreateVecs(mat,&ones,NULL));
5031   PetscCall(VecSet(ones,1.));
5032   PetscCall(MatMult(mat,ones,v));
5033   PetscCall(VecDestroy(&ones));
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 /*@
5038    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
5039 
5040    Collective on Mat
5041 
5042    Input Parameters:
5043 +  mat - the matrix to transpose
5044 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5045 
5046    Output Parameter:
5047 .  B - the transpose
5048 
5049    Notes:
5050      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
5051 
5052      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
5053 
5054      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
5055 
5056    Level: intermediate
5057 
5058 .seealso: `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`
5059 @*/
5060 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
5061 {
5062   PetscFunctionBegin;
5063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5064   PetscValidType(mat,1);
5065   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5066   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5067   PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5068   PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
5069   PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
5070   MatCheckPreallocated(mat,1);
5071 
5072   PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0));
5073   PetscCall((*mat->ops->transpose)(mat,reuse,B));
5074   PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0));
5075   if (B) PetscCall(PetscObjectStateIncrease((PetscObject)*B));
5076   PetscFunctionReturn(0);
5077 }
5078 
5079 /*@
5080    MatIsTranspose - Test whether a matrix is another one's transpose,
5081         or its own, in which case it tests symmetry.
5082 
5083    Collective on Mat
5084 
5085    Input Parameters:
5086 +  A - the matrix to test
5087 -  B - the matrix to test against, this can equal the first parameter
5088 
5089    Output Parameters:
5090 .  flg - the result
5091 
5092    Notes:
5093    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5094    has a running time of the order of the number of nonzeros; the parallel
5095    test involves parallel copies of the block-offdiagonal parts of the matrix.
5096 
5097    Level: intermediate
5098 
5099 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`
5100 @*/
5101 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
5102 {
5103   PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5104 
5105   PetscFunctionBegin;
5106   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5107   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5108   PetscValidBoolPointer(flg,4);
5109   PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f));
5110   PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g));
5111   *flg = PETSC_FALSE;
5112   if (f && g) {
5113     PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5114     PetscCall((*f)(A,B,tol,flg));
5115   } else {
5116     MatType mattype;
5117 
5118     PetscCall(MatGetType(f ? B : A,&mattype));
5119     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
5120   }
5121   PetscFunctionReturn(0);
5122 }
5123 
5124 /*@
5125    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5126 
5127    Collective on Mat
5128 
5129    Input Parameters:
5130 +  mat - the matrix to transpose and complex conjugate
5131 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5132 
5133    Output Parameter:
5134 .  B - the Hermitian
5135 
5136    Level: intermediate
5137 
5138 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`
5139 @*/
5140 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5141 {
5142   PetscFunctionBegin;
5143   PetscCall(MatTranspose(mat,reuse,B));
5144 #if defined(PETSC_USE_COMPLEX)
5145   PetscCall(MatConjugate(*B));
5146 #endif
5147   PetscFunctionReturn(0);
5148 }
5149 
5150 /*@
5151    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5152 
5153    Collective on Mat
5154 
5155    Input Parameters:
5156 +  A - the matrix to test
5157 -  B - the matrix to test against, this can equal the first parameter
5158 
5159    Output Parameters:
5160 .  flg - the result
5161 
5162    Notes:
5163    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5164    has a running time of the order of the number of nonzeros; the parallel
5165    test involves parallel copies of the block-offdiagonal parts of the matrix.
5166 
5167    Level: intermediate
5168 
5169 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()`
5170 @*/
5171 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
5172 {
5173   PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5174 
5175   PetscFunctionBegin;
5176   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5177   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5178   PetscValidBoolPointer(flg,4);
5179   PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f));
5180   PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g));
5181   if (f && g) {
5182     PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5183     PetscCall((*f)(A,B,tol,flg));
5184   }
5185   PetscFunctionReturn(0);
5186 }
5187 
5188 /*@
5189    MatPermute - Creates a new matrix with rows and columns permuted from the
5190    original.
5191 
5192    Collective on Mat
5193 
5194    Input Parameters:
5195 +  mat - the matrix to permute
5196 .  row - row permutation, each processor supplies only the permutation for its rows
5197 -  col - column permutation, each processor supplies only the permutation for its columns
5198 
5199    Output Parameters:
5200 .  B - the permuted matrix
5201 
5202    Level: advanced
5203 
5204    Note:
5205    The index sets map from row/col of permuted matrix to row/col of original matrix.
5206    The index sets should be on the same communicator as Mat and have the same local sizes.
5207 
5208    Developer Note:
5209      If you want to implement MatPermute for a matrix type, and your approach doesn't
5210      exploit the fact that row and col are permutations, consider implementing the
5211      more general MatCreateSubMatrix() instead.
5212 
5213 .seealso: `MatGetOrdering()`, `ISAllGather()`
5214 
5215 @*/
5216 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5217 {
5218   PetscFunctionBegin;
5219   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5220   PetscValidType(mat,1);
5221   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5222   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5223   PetscValidPointer(B,4);
5224   PetscCheckSameComm(mat,1,row,2);
5225   if (row != col) PetscCheckSameComm(row,2,col,3);
5226   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5227   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5228   PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5229   MatCheckPreallocated(mat,1);
5230 
5231   if (mat->ops->permute) {
5232     PetscCall((*mat->ops->permute)(mat,row,col,B));
5233     PetscCall(PetscObjectStateIncrease((PetscObject)*B));
5234   } else {
5235     PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B));
5236   }
5237   PetscFunctionReturn(0);
5238 }
5239 
5240 /*@
5241    MatEqual - Compares two matrices.
5242 
5243    Collective on Mat
5244 
5245    Input Parameters:
5246 +  A - the first matrix
5247 -  B - the second matrix
5248 
5249    Output Parameter:
5250 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5251 
5252    Level: intermediate
5253 
5254 @*/
5255 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
5256 {
5257   PetscFunctionBegin;
5258   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5259   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5260   PetscValidType(A,1);
5261   PetscValidType(B,2);
5262   PetscValidBoolPointer(flg,3);
5263   PetscCheckSameComm(A,1,B,2);
5264   MatCheckPreallocated(A,1);
5265   MatCheckPreallocated(B,2);
5266   PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5267   PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5268   PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
5269   if (A->ops->equal && A->ops->equal == B->ops->equal) {
5270     PetscCall((*A->ops->equal)(A,B,flg));
5271   } else {
5272     PetscCall(MatMultEqual(A,B,10,flg));
5273   }
5274   PetscFunctionReturn(0);
5275 }
5276 
5277 /*@
5278    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5279    matrices that are stored as vectors.  Either of the two scaling
5280    matrices can be NULL.
5281 
5282    Collective on Mat
5283 
5284    Input Parameters:
5285 +  mat - the matrix to be scaled
5286 .  l - the left scaling vector (or NULL)
5287 -  r - the right scaling vector (or NULL)
5288 
5289    Notes:
5290    MatDiagonalScale() computes A = LAR, where
5291    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5292    The L scales the rows of the matrix, the R scales the columns of the matrix.
5293 
5294    Level: intermediate
5295 
5296 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()`
5297 @*/
5298 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5299 {
5300   PetscFunctionBegin;
5301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5302   PetscValidType(mat,1);
5303   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5304   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5305   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5306   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5307   MatCheckPreallocated(mat,1);
5308   if (!l && !r) PetscFunctionReturn(0);
5309 
5310   PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5311   PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0));
5312   PetscCall((*mat->ops->diagonalscale)(mat,l,r));
5313   PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0));
5314   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
5315   if (l != r && mat->symmetric) mat->symmetric = PETSC_FALSE;
5316   PetscFunctionReturn(0);
5317 }
5318 
5319 /*@
5320     MatScale - Scales all elements of a matrix by a given number.
5321 
5322     Logically Collective on Mat
5323 
5324     Input Parameters:
5325 +   mat - the matrix to be scaled
5326 -   a  - the scaling value
5327 
5328     Output Parameter:
5329 .   mat - the scaled matrix
5330 
5331     Level: intermediate
5332 
5333 .seealso: `MatDiagonalScale()`
5334 @*/
5335 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5336 {
5337   PetscFunctionBegin;
5338   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5339   PetscValidType(mat,1);
5340   PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5341   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5342   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5343   PetscValidLogicalCollectiveScalar(mat,a,2);
5344   MatCheckPreallocated(mat,1);
5345 
5346   PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0));
5347   if (a != (PetscScalar)1.0) {
5348     PetscCall((*mat->ops->scale)(mat,a));
5349     PetscCall(PetscObjectStateIncrease((PetscObject)mat));
5350   }
5351   PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0));
5352   PetscFunctionReturn(0);
5353 }
5354 
5355 /*@
5356    MatNorm - Calculates various norms of a matrix.
5357 
5358    Collective on Mat
5359 
5360    Input Parameters:
5361 +  mat - the matrix
5362 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5363 
5364    Output Parameter:
5365 .  nrm - the resulting norm
5366 
5367    Level: intermediate
5368 
5369 @*/
5370 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5371 {
5372   PetscFunctionBegin;
5373   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5374   PetscValidType(mat,1);
5375   PetscValidRealPointer(nrm,3);
5376 
5377   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5378   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5379   PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5380   MatCheckPreallocated(mat,1);
5381 
5382   PetscCall((*mat->ops->norm)(mat,type,nrm));
5383   PetscFunctionReturn(0);
5384 }
5385 
5386 /*
5387      This variable is used to prevent counting of MatAssemblyBegin() that
5388    are called from within a MatAssemblyEnd().
5389 */
5390 static PetscInt MatAssemblyEnd_InUse = 0;
5391 /*@
5392    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5393    be called after completing all calls to MatSetValues().
5394 
5395    Collective on Mat
5396 
5397    Input Parameters:
5398 +  mat - the matrix
5399 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5400 
5401    Notes:
5402    MatSetValues() generally caches the values.  The matrix is ready to
5403    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5404    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5405    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5406    using the matrix.
5407 
5408    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5409    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
5410    a global collective operation requring all processes that share the matrix.
5411 
5412    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5413    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5414    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5415 
5416    Level: beginner
5417 
5418 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()`
5419 @*/
5420 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5421 {
5422   PetscFunctionBegin;
5423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5424   PetscValidType(mat,1);
5425   MatCheckPreallocated(mat,1);
5426   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5427   if (mat->assembled) {
5428     mat->was_assembled = PETSC_TRUE;
5429     mat->assembled     = PETSC_FALSE;
5430   }
5431 
5432   if (!MatAssemblyEnd_InUse) {
5433     PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0));
5434     if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type));
5435     PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0));
5436   } else if (mat->ops->assemblybegin) {
5437     PetscCall((*mat->ops->assemblybegin)(mat,type));
5438   }
5439   PetscFunctionReturn(0);
5440 }
5441 
5442 /*@
5443    MatAssembled - Indicates if a matrix has been assembled and is ready for
5444      use; for example, in matrix-vector product.
5445 
5446    Not Collective
5447 
5448    Input Parameter:
5449 .  mat - the matrix
5450 
5451    Output Parameter:
5452 .  assembled - PETSC_TRUE or PETSC_FALSE
5453 
5454    Level: advanced
5455 
5456 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()`
5457 @*/
5458 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5459 {
5460   PetscFunctionBegin;
5461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5462   PetscValidBoolPointer(assembled,2);
5463   *assembled = mat->assembled;
5464   PetscFunctionReturn(0);
5465 }
5466 
5467 /*@
5468    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5469    be called after MatAssemblyBegin().
5470 
5471    Collective on Mat
5472 
5473    Input Parameters:
5474 +  mat - the matrix
5475 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5476 
5477    Options Database Keys:
5478 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5479 .  -mat_view ::ascii_info_detail - Prints more detailed info
5480 .  -mat_view - Prints matrix in ASCII format
5481 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5482 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5483 .  -display <name> - Sets display name (default is host)
5484 .  -draw_pause <sec> - Sets number of seconds to pause after display
5485 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab)
5486 .  -viewer_socket_machine <machine> - Machine to use for socket
5487 .  -viewer_socket_port <port> - Port number to use for socket
5488 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5489 
5490    Notes:
5491    MatSetValues() generally caches the values.  The matrix is ready to
5492    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5493    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5494    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5495    using the matrix.
5496 
5497    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5498    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5499    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5500 
5501    Level: beginner
5502 
5503 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()`
5504 @*/
5505 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5506 {
5507   static PetscInt inassm = 0;
5508   PetscBool       flg    = PETSC_FALSE;
5509 
5510   PetscFunctionBegin;
5511   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5512   PetscValidType(mat,1);
5513 
5514   inassm++;
5515   MatAssemblyEnd_InUse++;
5516   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5517     PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0));
5518     if (mat->ops->assemblyend) {
5519       PetscCall((*mat->ops->assemblyend)(mat,type));
5520     }
5521     PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0));
5522   } else if (mat->ops->assemblyend) {
5523     PetscCall((*mat->ops->assemblyend)(mat,type));
5524   }
5525 
5526   /* Flush assembly is not a true assembly */
5527   if (type != MAT_FLUSH_ASSEMBLY) {
5528     mat->num_ass++;
5529     mat->assembled        = PETSC_TRUE;
5530     mat->ass_nonzerostate = mat->nonzerostate;
5531   }
5532 
5533   mat->insertmode = NOT_SET_VALUES;
5534   MatAssemblyEnd_InUse--;
5535   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
5536   if (!mat->symmetric_eternal) {
5537     mat->symmetric_set              = PETSC_FALSE;
5538     mat->hermitian_set              = PETSC_FALSE;
5539     mat->structurally_symmetric_set = PETSC_FALSE;
5540   }
5541   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5542     PetscCall(MatViewFromOptions(mat,NULL,"-mat_view"));
5543 
5544     if (mat->checksymmetryonassembly) {
5545       PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg));
5546       if (flg) {
5547         PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol));
5548       } else {
5549         PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol));
5550       }
5551     }
5552     if (mat->nullsp && mat->checknullspaceonassembly) {
5553       PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL));
5554     }
5555   }
5556   inassm--;
5557   PetscFunctionReturn(0);
5558 }
5559 
5560 /*@
5561    MatSetOption - Sets a parameter option for a matrix. Some options
5562    may be specific to certain storage formats.  Some options
5563    determine how values will be inserted (or added). Sorted,
5564    row-oriented input will generally assemble the fastest. The default
5565    is row-oriented.
5566 
5567    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5568 
5569    Input Parameters:
5570 +  mat - the matrix
5571 .  option - the option, one of those listed below (and possibly others),
5572 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5573 
5574   Options Describing Matrix Structure:
5575 +    MAT_SPD - symmetric positive definite
5576 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5577 .    MAT_HERMITIAN - transpose is the complex conjugation
5578 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5579 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5580                             you set to be kept with all future use of the matrix
5581                             including after MatAssemblyBegin/End() which could
5582                             potentially change the symmetry structure, i.e. you
5583                             KNOW the matrix will ALWAYS have the property you set.
5584                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5585                             the relevant flags must be set independently.
5586 
5587    Options For Use with MatSetValues():
5588    Insert a logically dense subblock, which can be
5589 .    MAT_ROW_ORIENTED - row-oriented (default)
5590 
5591    Note these options reflect the data you pass in with MatSetValues(); it has
5592    nothing to do with how the data is stored internally in the matrix
5593    data structure.
5594 
5595    When (re)assembling a matrix, we can restrict the input for
5596    efficiency/debugging purposes.  These options include
5597 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5598 .    MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated
5599 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5600 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5601 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5602 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5603         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5604         performance for very large process counts.
5605 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5606         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5607         functions, instead sending only neighbor messages.
5608 
5609    Notes:
5610    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5611 
5612    Some options are relevant only for particular matrix types and
5613    are thus ignored by others.  Other options are not supported by
5614    certain matrix types and will generate an error message if set.
5615 
5616    If using a Fortran 77 module to compute a matrix, one may need to
5617    use the column-oriented option (or convert to the row-oriented
5618    format).
5619 
5620    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5621    that would generate a new entry in the nonzero structure is instead
5622    ignored.  Thus, if memory has not alredy been allocated for this particular
5623    data, then the insertion is ignored. For dense matrices, in which
5624    the entire array is allocated, no entries are ever ignored.
5625    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5626 
5627    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5628    that would generate a new entry in the nonzero structure instead produces
5629    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
5630 
5631    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5632    that would generate a new entry that has not been preallocated will
5633    instead produce an error. (Currently supported for AIJ and BAIJ formats
5634    only.) This is a useful flag when debugging matrix memory preallocation.
5635    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5636 
5637    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5638    other processors should be dropped, rather than stashed.
5639    This is useful if you know that the "owning" processor is also
5640    always generating the correct matrix entries, so that PETSc need
5641    not transfer duplicate entries generated on another processor.
5642 
5643    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5644    searches during matrix assembly. When this flag is set, the hash table
5645    is created during the first Matrix Assembly. This hash table is
5646    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5647    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5648    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5649    supported by MATMPIBAIJ format only.
5650 
5651    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5652    are kept in the nonzero structure
5653 
5654    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5655    a zero location in the matrix
5656 
5657    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5658 
5659    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5660         zero row routines and thus improves performance for very large process counts.
5661 
5662    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5663         part of the matrix (since they should match the upper triangular part).
5664 
5665    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5666                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5667                      with finite difference schemes with non-periodic boundary conditions.
5668 
5669    Level: intermediate
5670 
5671 .seealso: `MatOption`, `Mat`
5672 
5673 @*/
5674 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5675 {
5676   PetscFunctionBegin;
5677   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5678   if (op > 0) {
5679     PetscValidLogicalCollectiveEnum(mat,op,2);
5680     PetscValidLogicalCollectiveBool(mat,flg,3);
5681   }
5682 
5683   PetscCheck(((int) op) > MAT_OPTION_MIN && ((int) op) < MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5684 
5685   switch (op) {
5686   case MAT_FORCE_DIAGONAL_ENTRIES:
5687     mat->force_diagonals = flg;
5688     PetscFunctionReturn(0);
5689   case MAT_NO_OFF_PROC_ENTRIES:
5690     mat->nooffprocentries = flg;
5691     PetscFunctionReturn(0);
5692   case MAT_SUBSET_OFF_PROC_ENTRIES:
5693     mat->assembly_subset = flg;
5694     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5695 #if !defined(PETSC_HAVE_MPIUNI)
5696       PetscCall(MatStashScatterDestroy_BTS(&mat->stash));
5697 #endif
5698       mat->stash.first_assembly_done = PETSC_FALSE;
5699     }
5700     PetscFunctionReturn(0);
5701   case MAT_NO_OFF_PROC_ZERO_ROWS:
5702     mat->nooffproczerorows = flg;
5703     PetscFunctionReturn(0);
5704   case MAT_SPD:
5705     mat->spd_set = PETSC_TRUE;
5706     mat->spd     = flg;
5707     if (flg) {
5708       mat->symmetric                  = PETSC_TRUE;
5709       mat->structurally_symmetric     = PETSC_TRUE;
5710       mat->symmetric_set              = PETSC_TRUE;
5711       mat->structurally_symmetric_set = PETSC_TRUE;
5712     }
5713     break;
5714   case MAT_SYMMETRIC:
5715     mat->symmetric = flg;
5716     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5717     mat->symmetric_set              = PETSC_TRUE;
5718     mat->structurally_symmetric_set = flg;
5719 #if !defined(PETSC_USE_COMPLEX)
5720     mat->hermitian     = flg;
5721     mat->hermitian_set = PETSC_TRUE;
5722 #endif
5723     break;
5724   case MAT_HERMITIAN:
5725     mat->hermitian = flg;
5726     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5727     mat->hermitian_set              = PETSC_TRUE;
5728     mat->structurally_symmetric_set = flg;
5729 #if !defined(PETSC_USE_COMPLEX)
5730     mat->symmetric     = flg;
5731     mat->symmetric_set = PETSC_TRUE;
5732 #endif
5733     break;
5734   case MAT_STRUCTURALLY_SYMMETRIC:
5735     mat->structurally_symmetric     = flg;
5736     mat->structurally_symmetric_set = PETSC_TRUE;
5737     break;
5738   case MAT_SYMMETRY_ETERNAL:
5739     mat->symmetric_eternal = flg;
5740     break;
5741   case MAT_STRUCTURE_ONLY:
5742     mat->structure_only = flg;
5743     break;
5744   case MAT_SORTED_FULL:
5745     mat->sortedfull = flg;
5746     break;
5747   default:
5748     break;
5749   }
5750   if (mat->ops->setoption) {
5751     PetscCall((*mat->ops->setoption)(mat,op,flg));
5752   }
5753   PetscFunctionReturn(0);
5754 }
5755 
5756 /*@
5757    MatGetOption - Gets a parameter option that has been set for a matrix.
5758 
5759    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5760 
5761    Input Parameters:
5762 +  mat - the matrix
5763 -  option - the option, this only responds to certain options, check the code for which ones
5764 
5765    Output Parameter:
5766 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5767 
5768     Notes:
5769     Can only be called after MatSetSizes() and MatSetType() have been set.
5770 
5771    Level: intermediate
5772 
5773 .seealso: `MatOption`, `MatSetOption()`
5774 
5775 @*/
5776 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5777 {
5778   PetscFunctionBegin;
5779   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5780   PetscValidType(mat,1);
5781 
5782   PetscCheck(((int) op) > MAT_OPTION_MIN && ((int) op) < MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5783   PetscCheck(((PetscObject)mat)->type_name,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5784 
5785   switch (op) {
5786   case MAT_NO_OFF_PROC_ENTRIES:
5787     *flg = mat->nooffprocentries;
5788     break;
5789   case MAT_NO_OFF_PROC_ZERO_ROWS:
5790     *flg = mat->nooffproczerorows;
5791     break;
5792   case MAT_SYMMETRIC:
5793     *flg = mat->symmetric;
5794     break;
5795   case MAT_HERMITIAN:
5796     *flg = mat->hermitian;
5797     break;
5798   case MAT_STRUCTURALLY_SYMMETRIC:
5799     *flg = mat->structurally_symmetric;
5800     break;
5801   case MAT_SYMMETRY_ETERNAL:
5802     *flg = mat->symmetric_eternal;
5803     break;
5804   case MAT_SPD:
5805     *flg = mat->spd;
5806     break;
5807   default:
5808     break;
5809   }
5810   PetscFunctionReturn(0);
5811 }
5812 
5813 /*@
5814    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5815    this routine retains the old nonzero structure.
5816 
5817    Logically Collective on Mat
5818 
5819    Input Parameters:
5820 .  mat - the matrix
5821 
5822    Level: intermediate
5823 
5824    Notes:
5825     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.
5826    See the Performance chapter of the users manual for information on preallocating matrices.
5827 
5828 .seealso: `MatZeroRows()`
5829 @*/
5830 PetscErrorCode MatZeroEntries(Mat mat)
5831 {
5832   PetscFunctionBegin;
5833   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5834   PetscValidType(mat,1);
5835   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5836   PetscCheck(mat->insertmode == NOT_SET_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5837   PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5838   MatCheckPreallocated(mat,1);
5839 
5840   PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0));
5841   PetscCall((*mat->ops->zeroentries)(mat));
5842   PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0));
5843   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
5844   PetscFunctionReturn(0);
5845 }
5846 
5847 /*@
5848    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5849    of a set of rows and columns of a matrix.
5850 
5851    Collective on Mat
5852 
5853    Input Parameters:
5854 +  mat - the matrix
5855 .  numRows - the number of rows to remove
5856 .  rows - the global row indices
5857 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5858 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5859 -  b - optional vector of right hand side, that will be adjusted by provided solution
5860 
5861    Notes:
5862    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5863 
5864    The user can set a value in the diagonal entry (or for the AIJ and
5865    row formats can optionally remove the main diagonal entry from the
5866    nonzero structure as well, by passing 0.0 as the final argument).
5867 
5868    For the parallel case, all processes that share the matrix (i.e.,
5869    those in the communicator used for matrix creation) MUST call this
5870    routine, regardless of whether any rows being zeroed are owned by
5871    them.
5872 
5873    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5874    list only rows local to itself).
5875 
5876    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5877 
5878    Level: intermediate
5879 
5880 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
5881           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
5882 @*/
5883 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5884 {
5885   PetscFunctionBegin;
5886   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5887   PetscValidType(mat,1);
5888   if (numRows) PetscValidIntPointer(rows,3);
5889   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5890   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5891   PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5892   MatCheckPreallocated(mat,1);
5893 
5894   PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b));
5895   PetscCall(MatViewFromOptions(mat,NULL,"-mat_view"));
5896   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
5897   PetscFunctionReturn(0);
5898 }
5899 
5900 /*@
5901    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5902    of a set of rows and columns of a matrix.
5903 
5904    Collective on Mat
5905 
5906    Input Parameters:
5907 +  mat - the matrix
5908 .  is - the rows to zero
5909 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5910 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5911 -  b - optional vector of right hand side, that will be adjusted by provided solution
5912 
5913    Notes:
5914    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5915 
5916    The user can set a value in the diagonal entry (or for the AIJ and
5917    row formats can optionally remove the main diagonal entry from the
5918    nonzero structure as well, by passing 0.0 as the final argument).
5919 
5920    For the parallel case, all processes that share the matrix (i.e.,
5921    those in the communicator used for matrix creation) MUST call this
5922    routine, regardless of whether any rows being zeroed are owned by
5923    them.
5924 
5925    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5926    list only rows local to itself).
5927 
5928    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5929 
5930    Level: intermediate
5931 
5932 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
5933           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()`
5934 @*/
5935 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5936 {
5937   PetscInt       numRows;
5938   const PetscInt *rows;
5939 
5940   PetscFunctionBegin;
5941   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5942   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5943   PetscValidType(mat,1);
5944   PetscValidType(is,2);
5945   PetscCall(ISGetLocalSize(is,&numRows));
5946   PetscCall(ISGetIndices(is,&rows));
5947   PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b));
5948   PetscCall(ISRestoreIndices(is,&rows));
5949   PetscFunctionReturn(0);
5950 }
5951 
5952 /*@
5953    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5954    of a set of rows of a matrix.
5955 
5956    Collective on Mat
5957 
5958    Input Parameters:
5959 +  mat - the matrix
5960 .  numRows - the number of rows to remove
5961 .  rows - the global row indices
5962 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5963 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5964 -  b - optional vector of right hand side, that will be adjusted by provided solution
5965 
5966    Notes:
5967    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5968    but does not release memory.  For the dense and block diagonal
5969    formats this does not alter the nonzero structure.
5970 
5971    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5972    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5973    merely zeroed.
5974 
5975    The user can set a value in the diagonal entry (or for the AIJ and
5976    row formats can optionally remove the main diagonal entry from the
5977    nonzero structure as well, by passing 0.0 as the final argument).
5978 
5979    For the parallel case, all processes that share the matrix (i.e.,
5980    those in the communicator used for matrix creation) MUST call this
5981    routine, regardless of whether any rows being zeroed are owned by
5982    them.
5983 
5984    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5985    list only rows local to itself).
5986 
5987    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5988    owns that are to be zeroed. This saves a global synchronization in the implementation.
5989 
5990    Level: intermediate
5991 
5992 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
5993           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
5994 @*/
5995 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5996 {
5997   PetscFunctionBegin;
5998   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5999   PetscValidType(mat,1);
6000   if (numRows) PetscValidIntPointer(rows,3);
6001   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6002   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6003   PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6004   MatCheckPreallocated(mat,1);
6005 
6006   PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b));
6007   PetscCall(MatViewFromOptions(mat,NULL,"-mat_view"));
6008   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
6009   PetscFunctionReturn(0);
6010 }
6011 
6012 /*@
6013    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
6014    of a set of rows of a matrix.
6015 
6016    Collective on Mat
6017 
6018    Input Parameters:
6019 +  mat - the matrix
6020 .  is - index set of rows to remove (if NULL then no row is removed)
6021 .  diag - value put in all diagonals of eliminated rows
6022 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6023 -  b - optional vector of right hand side, that will be adjusted by provided solution
6024 
6025    Notes:
6026    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6027    but does not release memory.  For the dense and block diagonal
6028    formats this does not alter the nonzero structure.
6029 
6030    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6031    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6032    merely zeroed.
6033 
6034    The user can set a value in the diagonal entry (or for the AIJ and
6035    row formats can optionally remove the main diagonal entry from the
6036    nonzero structure as well, by passing 0.0 as the final argument).
6037 
6038    For the parallel case, all processes that share the matrix (i.e.,
6039    those in the communicator used for matrix creation) MUST call this
6040    routine, regardless of whether any rows being zeroed are owned by
6041    them.
6042 
6043    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6044    list only rows local to itself).
6045 
6046    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6047    owns that are to be zeroed. This saves a global synchronization in the implementation.
6048 
6049    Level: intermediate
6050 
6051 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6052           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6053 @*/
6054 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6055 {
6056   PetscInt       numRows = 0;
6057   const PetscInt *rows = NULL;
6058 
6059   PetscFunctionBegin;
6060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6061   PetscValidType(mat,1);
6062   if (is) {
6063     PetscValidHeaderSpecific(is,IS_CLASSID,2);
6064     PetscCall(ISGetLocalSize(is,&numRows));
6065     PetscCall(ISGetIndices(is,&rows));
6066   }
6067   PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b));
6068   if (is) {
6069     PetscCall(ISRestoreIndices(is,&rows));
6070   }
6071   PetscFunctionReturn(0);
6072 }
6073 
6074 /*@
6075    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6076    of a set of rows of a matrix. These rows must be local to the process.
6077 
6078    Collective on Mat
6079 
6080    Input Parameters:
6081 +  mat - the matrix
6082 .  numRows - the number of rows to remove
6083 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6084 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6085 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6086 -  b - optional vector of right hand side, that will be adjusted by provided solution
6087 
6088    Notes:
6089    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6090    but does not release memory.  For the dense and block diagonal
6091    formats this does not alter the nonzero structure.
6092 
6093    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6094    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6095    merely zeroed.
6096 
6097    The user can set a value in the diagonal entry (or for the AIJ and
6098    row formats can optionally remove the main diagonal entry from the
6099    nonzero structure as well, by passing 0.0 as the final argument).
6100 
6101    For the parallel case, all processes that share the matrix (i.e.,
6102    those in the communicator used for matrix creation) MUST call this
6103    routine, regardless of whether any rows being zeroed are owned by
6104    them.
6105 
6106    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6107    list only rows local to itself).
6108 
6109    The grid coordinates are across the entire grid, not just the local portion
6110 
6111    In Fortran idxm and idxn should be declared as
6112 $     MatStencil idxm(4,m)
6113    and the values inserted using
6114 $    idxm(MatStencil_i,1) = i
6115 $    idxm(MatStencil_j,1) = j
6116 $    idxm(MatStencil_k,1) = k
6117 $    idxm(MatStencil_c,1) = c
6118    etc
6119 
6120    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6121    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6122    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6123    DM_BOUNDARY_PERIODIC boundary type.
6124 
6125    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
6126    a single value per point) you can skip filling those indices.
6127 
6128    Level: intermediate
6129 
6130 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6131           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6132 @*/
6133 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6134 {
6135   PetscInt       dim     = mat->stencil.dim;
6136   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6137   PetscInt       *dims   = mat->stencil.dims+1;
6138   PetscInt       *starts = mat->stencil.starts;
6139   PetscInt       *dxm    = (PetscInt*) rows;
6140   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6141 
6142   PetscFunctionBegin;
6143   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6144   PetscValidType(mat,1);
6145   if (numRows) PetscValidPointer(rows,3);
6146 
6147   PetscCall(PetscMalloc1(numRows, &jdxm));
6148   for (i = 0; i < numRows; ++i) {
6149     /* Skip unused dimensions (they are ordered k, j, i, c) */
6150     for (j = 0; j < 3-sdim; ++j) dxm++;
6151     /* Local index in X dir */
6152     tmp = *dxm++ - starts[0];
6153     /* Loop over remaining dimensions */
6154     for (j = 0; j < dim-1; ++j) {
6155       /* If nonlocal, set index to be negative */
6156       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6157       /* Update local index */
6158       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6159     }
6160     /* Skip component slot if necessary */
6161     if (mat->stencil.noc) dxm++;
6162     /* Local row number */
6163     if (tmp >= 0) {
6164       jdxm[numNewRows++] = tmp;
6165     }
6166   }
6167   PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b));
6168   PetscCall(PetscFree(jdxm));
6169   PetscFunctionReturn(0);
6170 }
6171 
6172 /*@
6173    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6174    of a set of rows and columns of a matrix.
6175 
6176    Collective on Mat
6177 
6178    Input Parameters:
6179 +  mat - the matrix
6180 .  numRows - the number of rows/columns to remove
6181 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6182 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6183 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6184 -  b - optional vector of right hand side, that will be adjusted by provided solution
6185 
6186    Notes:
6187    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6188    but does not release memory.  For the dense and block diagonal
6189    formats this does not alter the nonzero structure.
6190 
6191    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6192    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6193    merely zeroed.
6194 
6195    The user can set a value in the diagonal entry (or for the AIJ and
6196    row formats can optionally remove the main diagonal entry from the
6197    nonzero structure as well, by passing 0.0 as the final argument).
6198 
6199    For the parallel case, all processes that share the matrix (i.e.,
6200    those in the communicator used for matrix creation) MUST call this
6201    routine, regardless of whether any rows being zeroed are owned by
6202    them.
6203 
6204    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6205    list only rows local to itself, but the row/column numbers are given in local numbering).
6206 
6207    The grid coordinates are across the entire grid, not just the local portion
6208 
6209    In Fortran idxm and idxn should be declared as
6210 $     MatStencil idxm(4,m)
6211    and the values inserted using
6212 $    idxm(MatStencil_i,1) = i
6213 $    idxm(MatStencil_j,1) = j
6214 $    idxm(MatStencil_k,1) = k
6215 $    idxm(MatStencil_c,1) = c
6216    etc
6217 
6218    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6219    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6220    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6221    DM_BOUNDARY_PERIODIC boundary type.
6222 
6223    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
6224    a single value per point) you can skip filling those indices.
6225 
6226    Level: intermediate
6227 
6228 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6229           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()`
6230 @*/
6231 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6232 {
6233   PetscInt       dim     = mat->stencil.dim;
6234   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6235   PetscInt       *dims   = mat->stencil.dims+1;
6236   PetscInt       *starts = mat->stencil.starts;
6237   PetscInt       *dxm    = (PetscInt*) rows;
6238   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6239 
6240   PetscFunctionBegin;
6241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6242   PetscValidType(mat,1);
6243   if (numRows) PetscValidPointer(rows,3);
6244 
6245   PetscCall(PetscMalloc1(numRows, &jdxm));
6246   for (i = 0; i < numRows; ++i) {
6247     /* Skip unused dimensions (they are ordered k, j, i, c) */
6248     for (j = 0; j < 3-sdim; ++j) dxm++;
6249     /* Local index in X dir */
6250     tmp = *dxm++ - starts[0];
6251     /* Loop over remaining dimensions */
6252     for (j = 0; j < dim-1; ++j) {
6253       /* If nonlocal, set index to be negative */
6254       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6255       /* Update local index */
6256       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6257     }
6258     /* Skip component slot if necessary */
6259     if (mat->stencil.noc) dxm++;
6260     /* Local row number */
6261     if (tmp >= 0) {
6262       jdxm[numNewRows++] = tmp;
6263     }
6264   }
6265   PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b));
6266   PetscCall(PetscFree(jdxm));
6267   PetscFunctionReturn(0);
6268 }
6269 
6270 /*@C
6271    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6272    of a set of rows of a matrix; using local numbering of rows.
6273 
6274    Collective on Mat
6275 
6276    Input Parameters:
6277 +  mat - the matrix
6278 .  numRows - the number of rows to remove
6279 .  rows - the local row indices
6280 .  diag - value put in all diagonals of eliminated rows
6281 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6282 -  b - optional vector of right hand side, that will be adjusted by provided solution
6283 
6284    Notes:
6285    Before calling MatZeroRowsLocal(), the user must first set the
6286    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6287 
6288    For the AIJ matrix formats this removes the old nonzero structure,
6289    but does not release memory.  For the dense and block diagonal
6290    formats this does not alter the nonzero structure.
6291 
6292    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6293    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6294    merely zeroed.
6295 
6296    The user can set a value in the diagonal entry (or for the AIJ and
6297    row formats can optionally remove the main diagonal entry from the
6298    nonzero structure as well, by passing 0.0 as the final argument).
6299 
6300    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6301    owns that are to be zeroed. This saves a global synchronization in the implementation.
6302 
6303    Level: intermediate
6304 
6305 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`,
6306           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6307 @*/
6308 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6309 {
6310   PetscFunctionBegin;
6311   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6312   PetscValidType(mat,1);
6313   if (numRows) PetscValidIntPointer(rows,3);
6314   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6315   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6316   MatCheckPreallocated(mat,1);
6317 
6318   if (mat->ops->zerorowslocal) {
6319     PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b));
6320   } else {
6321     IS             is, newis;
6322     const PetscInt *newRows;
6323 
6324     PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6325     PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is));
6326     PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis));
6327     PetscCall(ISGetIndices(newis,&newRows));
6328     PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b));
6329     PetscCall(ISRestoreIndices(newis,&newRows));
6330     PetscCall(ISDestroy(&newis));
6331     PetscCall(ISDestroy(&is));
6332   }
6333   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
6334   PetscFunctionReturn(0);
6335 }
6336 
6337 /*@
6338    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6339    of a set of rows of a matrix; using local numbering of rows.
6340 
6341    Collective on Mat
6342 
6343    Input Parameters:
6344 +  mat - the matrix
6345 .  is - index set of rows to remove
6346 .  diag - value put in all diagonals of eliminated rows
6347 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6348 -  b - optional vector of right hand side, that will be adjusted by provided solution
6349 
6350    Notes:
6351    Before calling MatZeroRowsLocalIS(), the user must first set the
6352    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6353 
6354    For the AIJ matrix formats this removes the old nonzero structure,
6355    but does not release memory.  For the dense and block diagonal
6356    formats this does not alter the nonzero structure.
6357 
6358    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6359    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6360    merely zeroed.
6361 
6362    The user can set a value in the diagonal entry (or for the AIJ and
6363    row formats can optionally remove the main diagonal entry from the
6364    nonzero structure as well, by passing 0.0 as the final argument).
6365 
6366    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6367    owns that are to be zeroed. This saves a global synchronization in the implementation.
6368 
6369    Level: intermediate
6370 
6371 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6372           `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6373 @*/
6374 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6375 {
6376   PetscInt       numRows;
6377   const PetscInt *rows;
6378 
6379   PetscFunctionBegin;
6380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6381   PetscValidType(mat,1);
6382   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6383   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6384   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6385   MatCheckPreallocated(mat,1);
6386 
6387   PetscCall(ISGetLocalSize(is,&numRows));
6388   PetscCall(ISGetIndices(is,&rows));
6389   PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b));
6390   PetscCall(ISRestoreIndices(is,&rows));
6391   PetscFunctionReturn(0);
6392 }
6393 
6394 /*@
6395    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6396    of a set of rows and columns of a matrix; using local numbering of rows.
6397 
6398    Collective on Mat
6399 
6400    Input Parameters:
6401 +  mat - the matrix
6402 .  numRows - the number of rows to remove
6403 .  rows - the global row indices
6404 .  diag - value put in all diagonals of eliminated rows
6405 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6406 -  b - optional vector of right hand side, that will be adjusted by provided solution
6407 
6408    Notes:
6409    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6410    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6411 
6412    The user can set a value in the diagonal entry (or for the AIJ and
6413    row formats can optionally remove the main diagonal entry from the
6414    nonzero structure as well, by passing 0.0 as the final argument).
6415 
6416    Level: intermediate
6417 
6418 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6419           `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6420 @*/
6421 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6422 {
6423   IS             is, newis;
6424   const PetscInt *newRows;
6425 
6426   PetscFunctionBegin;
6427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6428   PetscValidType(mat,1);
6429   if (numRows) PetscValidIntPointer(rows,3);
6430   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6431   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6432   MatCheckPreallocated(mat,1);
6433 
6434   PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6435   PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is));
6436   PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis));
6437   PetscCall(ISGetIndices(newis,&newRows));
6438   PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b));
6439   PetscCall(ISRestoreIndices(newis,&newRows));
6440   PetscCall(ISDestroy(&newis));
6441   PetscCall(ISDestroy(&is));
6442   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
6443   PetscFunctionReturn(0);
6444 }
6445 
6446 /*@
6447    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6448    of a set of rows and columns of a matrix; using local numbering of rows.
6449 
6450    Collective on Mat
6451 
6452    Input Parameters:
6453 +  mat - the matrix
6454 .  is - index set of rows to remove
6455 .  diag - value put in all diagonals of eliminated rows
6456 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6457 -  b - optional vector of right hand side, that will be adjusted by provided solution
6458 
6459    Notes:
6460    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6461    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6462 
6463    The user can set a value in the diagonal entry (or for the AIJ and
6464    row formats can optionally remove the main diagonal entry from the
6465    nonzero structure as well, by passing 0.0 as the final argument).
6466 
6467    Level: intermediate
6468 
6469 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`,
6470           `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`
6471 @*/
6472 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6473 {
6474   PetscInt       numRows;
6475   const PetscInt *rows;
6476 
6477   PetscFunctionBegin;
6478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6479   PetscValidType(mat,1);
6480   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6481   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6482   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6483   MatCheckPreallocated(mat,1);
6484 
6485   PetscCall(ISGetLocalSize(is,&numRows));
6486   PetscCall(ISGetIndices(is,&rows));
6487   PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b));
6488   PetscCall(ISRestoreIndices(is,&rows));
6489   PetscFunctionReturn(0);
6490 }
6491 
6492 /*@C
6493    MatGetSize - Returns the numbers of rows and columns in a matrix.
6494 
6495    Not Collective
6496 
6497    Input Parameter:
6498 .  mat - the matrix
6499 
6500    Output Parameters:
6501 +  m - the number of global rows
6502 -  n - the number of global columns
6503 
6504    Note: both output parameters can be NULL on input.
6505 
6506    Level: beginner
6507 
6508 .seealso: `MatGetLocalSize()`
6509 @*/
6510 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6511 {
6512   PetscFunctionBegin;
6513   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6514   if (m) *m = mat->rmap->N;
6515   if (n) *n = mat->cmap->N;
6516   PetscFunctionReturn(0);
6517 }
6518 
6519 /*@C
6520    MatGetLocalSize - Returns the number of local rows and local columns
6521    of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs().
6522 
6523    Not Collective
6524 
6525    Input Parameter:
6526 .  mat - the matrix
6527 
6528    Output Parameters:
6529 +  m - the number of local rows
6530 -  n - the number of local columns
6531 
6532    Note: both output parameters can be NULL on input.
6533 
6534    Level: beginner
6535 
6536 .seealso: `MatGetSize()`
6537 @*/
6538 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6539 {
6540   PetscFunctionBegin;
6541   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6542   if (m) PetscValidIntPointer(m,2);
6543   if (n) PetscValidIntPointer(n,3);
6544   if (m) *m = mat->rmap->n;
6545   if (n) *n = mat->cmap->n;
6546   PetscFunctionReturn(0);
6547 }
6548 
6549 /*@C
6550    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6551    this processor. (The columns of the "diagonal block")
6552 
6553    Not Collective, unless matrix has not been allocated, then collective on Mat
6554 
6555    Input Parameter:
6556 .  mat - the matrix
6557 
6558    Output Parameters:
6559 +  m - the global index of the first local column
6560 -  n - one more than the global index of the last local column
6561 
6562    Notes:
6563     both output parameters can be NULL on input.
6564 
6565    Level: developer
6566 
6567 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`
6568 
6569 @*/
6570 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6571 {
6572   PetscFunctionBegin;
6573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6574   PetscValidType(mat,1);
6575   if (m) PetscValidIntPointer(m,2);
6576   if (n) PetscValidIntPointer(n,3);
6577   MatCheckPreallocated(mat,1);
6578   if (m) *m = mat->cmap->rstart;
6579   if (n) *n = mat->cmap->rend;
6580   PetscFunctionReturn(0);
6581 }
6582 
6583 /*@C
6584    MatGetOwnershipRange - Returns the range of matrix rows owned by
6585    this processor, assuming that the matrix is laid out with the first
6586    n1 rows on the first processor, the next n2 rows on the second, etc.
6587    For certain parallel layouts this range may not be well defined.
6588 
6589    Not Collective
6590 
6591    Input Parameter:
6592 .  mat - the matrix
6593 
6594    Output Parameters:
6595 +  m - the global index of the first local row
6596 -  n - one more than the global index of the last local row
6597 
6598    Note: Both output parameters can be NULL on input.
6599 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6600 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6601 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6602 
6603    Level: beginner
6604 
6605 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`
6606 
6607 @*/
6608 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6609 {
6610   PetscFunctionBegin;
6611   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6612   PetscValidType(mat,1);
6613   if (m) PetscValidIntPointer(m,2);
6614   if (n) PetscValidIntPointer(n,3);
6615   MatCheckPreallocated(mat,1);
6616   if (m) *m = mat->rmap->rstart;
6617   if (n) *n = mat->rmap->rend;
6618   PetscFunctionReturn(0);
6619 }
6620 
6621 /*@C
6622    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6623    each process
6624 
6625    Not Collective, unless matrix has not been allocated, then collective on Mat
6626 
6627    Input Parameters:
6628 .  mat - the matrix
6629 
6630    Output Parameters:
6631 .  ranges - start of each processors portion plus one more than the total length at the end
6632 
6633    Level: beginner
6634 
6635 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`
6636 
6637 @*/
6638 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6639 {
6640   PetscFunctionBegin;
6641   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6642   PetscValidType(mat,1);
6643   MatCheckPreallocated(mat,1);
6644   PetscCall(PetscLayoutGetRanges(mat->rmap,ranges));
6645   PetscFunctionReturn(0);
6646 }
6647 
6648 /*@C
6649    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6650    this processor. (The columns of the "diagonal blocks" for each process)
6651 
6652    Not Collective, unless matrix has not been allocated, then collective on Mat
6653 
6654    Input Parameters:
6655 .  mat - the matrix
6656 
6657    Output Parameters:
6658 .  ranges - start of each processors portion plus one more then the total length at the end
6659 
6660    Level: beginner
6661 
6662 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()`
6663 
6664 @*/
6665 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6666 {
6667   PetscFunctionBegin;
6668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6669   PetscValidType(mat,1);
6670   MatCheckPreallocated(mat,1);
6671   PetscCall(PetscLayoutGetRanges(mat->cmap,ranges));
6672   PetscFunctionReturn(0);
6673 }
6674 
6675 /*@C
6676    MatGetOwnershipIS - Get row and column ownership as index sets
6677 
6678    Not Collective
6679 
6680    Input Parameter:
6681 .  A - matrix
6682 
6683    Output Parameters:
6684 +  rows - rows in which this process owns elements
6685 -  cols - columns in which this process owns elements
6686 
6687    Level: intermediate
6688 
6689 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, `MATELEMENTAL`, `MATSCALAPACK`
6690 @*/
6691 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6692 {
6693   PetscErrorCode (*f)(Mat,IS*,IS*);
6694 
6695   PetscFunctionBegin;
6696   MatCheckPreallocated(A,1);
6697   PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f));
6698   if (f) {
6699     PetscCall((*f)(A,rows,cols));
6700   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6701     if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows));
6702     if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols));
6703   }
6704   PetscFunctionReturn(0);
6705 }
6706 
6707 /*@C
6708    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6709    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6710    to complete the factorization.
6711 
6712    Collective on Mat
6713 
6714    Input Parameters:
6715 +  mat - the matrix
6716 .  row - row permutation
6717 .  column - column permutation
6718 -  info - structure containing
6719 $      levels - number of levels of fill.
6720 $      expected fill - as ratio of original fill.
6721 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6722                 missing diagonal entries)
6723 
6724    Output Parameters:
6725 .  fact - new matrix that has been symbolically factored
6726 
6727    Notes:
6728     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6729 
6730    Most users should employ the simplified KSP interface for linear solvers
6731    instead of working directly with matrix algebra routines such as this.
6732    See, e.g., KSPCreate().
6733 
6734    Level: developer
6735 
6736 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`
6737           `MatGetOrdering()`, `MatFactorInfo`
6738 
6739     Note: this uses the definition of level of fill as in Y. Saad, 2003
6740 
6741     Developer Note: fortran interface is not autogenerated as the f90
6742     interface definition cannot be generated correctly [due to MatFactorInfo]
6743 
6744    References:
6745 .  * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6746 @*/
6747 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6748 {
6749   PetscFunctionBegin;
6750   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
6751   PetscValidType(mat,2);
6752   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3);
6753   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4);
6754   PetscValidPointer(info,5);
6755   PetscValidPointer(fact,1);
6756   PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels);
6757   PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6758   if (!fact->ops->ilufactorsymbolic) {
6759     MatSolverType stype;
6760     PetscCall(MatFactorGetSolverType(fact,&stype));
6761     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype);
6762   }
6763   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6764   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6765   MatCheckPreallocated(mat,2);
6766 
6767   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0));
6768   PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info));
6769   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0));
6770   PetscFunctionReturn(0);
6771 }
6772 
6773 /*@C
6774    MatICCFactorSymbolic - Performs symbolic incomplete
6775    Cholesky factorization for a symmetric matrix.  Use
6776    MatCholeskyFactorNumeric() to complete the factorization.
6777 
6778    Collective on Mat
6779 
6780    Input Parameters:
6781 +  mat - the matrix
6782 .  perm - row and column permutation
6783 -  info - structure containing
6784 $      levels - number of levels of fill.
6785 $      expected fill - as ratio of original fill.
6786 
6787    Output Parameter:
6788 .  fact - the factored matrix
6789 
6790    Notes:
6791    Most users should employ the KSP interface for linear solvers
6792    instead of working directly with matrix algebra routines such as this.
6793    See, e.g., KSPCreate().
6794 
6795    Level: developer
6796 
6797 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`
6798 
6799     Note: this uses the definition of level of fill as in Y. Saad, 2003
6800 
6801     Developer Note: fortran interface is not autogenerated as the f90
6802     interface definition cannot be generated correctly [due to MatFactorInfo]
6803 
6804    References:
6805 .  * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6806 @*/
6807 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6808 {
6809   PetscFunctionBegin;
6810   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
6811   PetscValidType(mat,2);
6812   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3);
6813   PetscValidPointer(info,4);
6814   PetscValidPointer(fact,1);
6815   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6816   PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels);
6817   PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6818   if (!(fact)->ops->iccfactorsymbolic) {
6819     MatSolverType stype;
6820     PetscCall(MatFactorGetSolverType(fact,&stype));
6821     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype);
6822   }
6823   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6824   MatCheckPreallocated(mat,2);
6825 
6826   if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0));
6827   PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info));
6828   if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0));
6829   PetscFunctionReturn(0);
6830 }
6831 
6832 /*@C
6833    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6834    points to an array of valid matrices, they may be reused to store the new
6835    submatrices.
6836 
6837    Collective on Mat
6838 
6839    Input Parameters:
6840 +  mat - the matrix
6841 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6842 .  irow, icol - index sets of rows and columns to extract
6843 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6844 
6845    Output Parameter:
6846 .  submat - the array of submatrices
6847 
6848    Notes:
6849    MatCreateSubMatrices() can extract ONLY sequential submatrices
6850    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6851    to extract a parallel submatrix.
6852 
6853    Some matrix types place restrictions on the row and column
6854    indices, such as that they be sorted or that they be equal to each other.
6855 
6856    The index sets may not have duplicate entries.
6857 
6858    When extracting submatrices from a parallel matrix, each processor can
6859    form a different submatrix by setting the rows and columns of its
6860    individual index sets according to the local submatrix desired.
6861 
6862    When finished using the submatrices, the user should destroy
6863    them with MatDestroySubMatrices().
6864 
6865    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6866    original matrix has not changed from that last call to MatCreateSubMatrices().
6867 
6868    This routine creates the matrices in submat; you should NOT create them before
6869    calling it. It also allocates the array of matrix pointers submat.
6870 
6871    For BAIJ matrices the index sets must respect the block structure, that is if they
6872    request one row/column in a block, they must request all rows/columns that are in
6873    that block. For example, if the block size is 2 you cannot request just row 0 and
6874    column 0.
6875 
6876    Fortran Note:
6877    The Fortran interface is slightly different from that given below; it
6878    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6879 
6880    Level: advanced
6881 
6882 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse`
6883 @*/
6884 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6885 {
6886   PetscInt       i;
6887   PetscBool      eq;
6888 
6889   PetscFunctionBegin;
6890   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6891   PetscValidType(mat,1);
6892   if (n) {
6893     PetscValidPointer(irow,3);
6894     for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3);
6895     PetscValidPointer(icol,4);
6896     for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4);
6897   }
6898   PetscValidPointer(submat,6);
6899   if (n && scall == MAT_REUSE_MATRIX) {
6900     PetscValidPointer(*submat,6);
6901     for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6);
6902   }
6903   PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6904   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6905   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6906   MatCheckPreallocated(mat,1);
6907   PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0));
6908   PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat));
6909   PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0));
6910   for (i=0; i<n; i++) {
6911     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6912     PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq));
6913     if (eq) {
6914       PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i]));
6915     }
6916 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6917     if (mat->boundtocpu && mat->bindingpropagates) {
6918       PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE));
6919       PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE));
6920     }
6921 #endif
6922   }
6923   PetscFunctionReturn(0);
6924 }
6925 
6926 /*@C
6927    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6928 
6929    Collective on Mat
6930 
6931    Input Parameters:
6932 +  mat - the matrix
6933 .  n   - the number of submatrixes to be extracted
6934 .  irow, icol - index sets of rows and columns to extract
6935 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6936 
6937    Output Parameter:
6938 .  submat - the array of submatrices
6939 
6940    Level: advanced
6941 
6942 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse`
6943 @*/
6944 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6945 {
6946   PetscInt       i;
6947   PetscBool      eq;
6948 
6949   PetscFunctionBegin;
6950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6951   PetscValidType(mat,1);
6952   if (n) {
6953     PetscValidPointer(irow,3);
6954     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6955     PetscValidPointer(icol,4);
6956     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6957   }
6958   PetscValidPointer(submat,6);
6959   if (n && scall == MAT_REUSE_MATRIX) {
6960     PetscValidPointer(*submat,6);
6961     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6962   }
6963   PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6964   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6965   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6966   MatCheckPreallocated(mat,1);
6967 
6968   PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0));
6969   PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat));
6970   PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0));
6971   for (i=0; i<n; i++) {
6972     PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq));
6973     if (eq) {
6974       PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i]));
6975     }
6976   }
6977   PetscFunctionReturn(0);
6978 }
6979 
6980 /*@C
6981    MatDestroyMatrices - Destroys an array of matrices.
6982 
6983    Collective on Mat
6984 
6985    Input Parameters:
6986 +  n - the number of local matrices
6987 -  mat - the matrices (note that this is a pointer to the array of matrices)
6988 
6989    Level: advanced
6990 
6991     Notes:
6992     Frees not only the matrices, but also the array that contains the matrices
6993            In Fortran will not free the array.
6994 
6995 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()`
6996 @*/
6997 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6998 {
6999   PetscInt       i;
7000 
7001   PetscFunctionBegin;
7002   if (!*mat) PetscFunctionReturn(0);
7003   PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n);
7004   PetscValidPointer(mat,2);
7005 
7006   for (i=0; i<n; i++) {
7007     PetscCall(MatDestroy(&(*mat)[i]));
7008   }
7009 
7010   /* memory is allocated even if n = 0 */
7011   PetscCall(PetscFree(*mat));
7012   PetscFunctionReturn(0);
7013 }
7014 
7015 /*@C
7016    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7017 
7018    Collective on Mat
7019 
7020    Input Parameters:
7021 +  n - the number of local matrices
7022 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7023                        sequence of MatCreateSubMatrices())
7024 
7025    Level: advanced
7026 
7027     Notes:
7028     Frees not only the matrices, but also the array that contains the matrices
7029            In Fortran will not free the array.
7030 
7031 .seealso: `MatCreateSubMatrices()`
7032 @*/
7033 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7034 {
7035   Mat            mat0;
7036 
7037   PetscFunctionBegin;
7038   if (!*mat) PetscFunctionReturn(0);
7039   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7040   PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n);
7041   PetscValidPointer(mat,2);
7042 
7043   mat0 = (*mat)[0];
7044   if (mat0 && mat0->ops->destroysubmatrices) {
7045     PetscCall((mat0->ops->destroysubmatrices)(n,mat));
7046   } else {
7047     PetscCall(MatDestroyMatrices(n,mat));
7048   }
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 /*@C
7053    MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process
7054 
7055    Collective on Mat
7056 
7057    Input Parameters:
7058 .  mat - the matrix
7059 
7060    Output Parameter:
7061 .  matstruct - the sequential matrix with the nonzero structure of mat
7062 
7063   Level: intermediate
7064 
7065 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()`
7066 @*/
7067 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7068 {
7069   PetscFunctionBegin;
7070   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7071   PetscValidPointer(matstruct,2);
7072 
7073   PetscValidType(mat,1);
7074   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7075   MatCheckPreallocated(mat,1);
7076 
7077   PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name);
7078   PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0));
7079   PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct));
7080   PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0));
7081   PetscFunctionReturn(0);
7082 }
7083 
7084 /*@C
7085    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7086 
7087    Collective on Mat
7088 
7089    Input Parameters:
7090 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7091                        sequence of MatGetSequentialNonzeroStructure())
7092 
7093    Level: advanced
7094 
7095     Notes:
7096     Frees not only the matrices, but also the array that contains the matrices
7097 
7098 .seealso: `MatGetSeqNonzeroStructure()`
7099 @*/
7100 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7101 {
7102   PetscFunctionBegin;
7103   PetscValidPointer(mat,1);
7104   PetscCall(MatDestroy(mat));
7105   PetscFunctionReturn(0);
7106 }
7107 
7108 /*@
7109    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7110    replaces the index sets by larger ones that represent submatrices with
7111    additional overlap.
7112 
7113    Collective on Mat
7114 
7115    Input Parameters:
7116 +  mat - the matrix
7117 .  n   - the number of index sets
7118 .  is  - the array of index sets (these index sets will changed during the call)
7119 -  ov  - the additional overlap requested
7120 
7121    Options Database:
7122 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7123 
7124    Level: developer
7125 
7126    Developer Note:
7127    Any implementation must preserve block sizes. That is: if the row block size and the column block size of mat are equal to bs, then the output index sets must be compatible with bs.
7128 
7129 .seealso: `MatCreateSubMatrices()`
7130 @*/
7131 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7132 {
7133   PetscInt       i,bs,cbs;
7134 
7135   PetscFunctionBegin;
7136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7137   PetscValidType(mat,1);
7138   PetscValidLogicalCollectiveInt(mat,n,2);
7139   PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n);
7140   if (n) {
7141     PetscValidPointer(is,3);
7142     for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3);
7143   }
7144   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7145   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7146   MatCheckPreallocated(mat,1);
7147 
7148   if (!ov || !n) PetscFunctionReturn(0);
7149   PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7150   PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0));
7151   PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov));
7152   PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0));
7153   PetscCall(MatGetBlockSizes(mat,&bs,&cbs));
7154   if (bs == cbs) {
7155     for (i=0; i<n; i++) {
7156       PetscCall(ISSetBlockSize(is[i],bs));
7157     }
7158   }
7159   PetscFunctionReturn(0);
7160 }
7161 
7162 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7163 
7164 /*@
7165    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7166    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7167    additional overlap.
7168 
7169    Collective on Mat
7170 
7171    Input Parameters:
7172 +  mat - the matrix
7173 .  n   - the number of index sets
7174 .  is  - the array of index sets (these index sets will changed during the call)
7175 -  ov  - the additional overlap requested
7176 
7177    Options Database:
7178 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7179 
7180    Level: developer
7181 
7182 .seealso: `MatCreateSubMatrices()`
7183 @*/
7184 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7185 {
7186   PetscInt       i;
7187 
7188   PetscFunctionBegin;
7189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7190   PetscValidType(mat,1);
7191   PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n);
7192   if (n) {
7193     PetscValidPointer(is,3);
7194     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7195   }
7196   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7197   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7198   MatCheckPreallocated(mat,1);
7199   if (!ov) PetscFunctionReturn(0);
7200   PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0));
7201   for (i=0; i<n; i++) {
7202     PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov));
7203   }
7204   PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0));
7205   PetscFunctionReturn(0);
7206 }
7207 
7208 /*@
7209    MatGetBlockSize - Returns the matrix block size.
7210 
7211    Not Collective
7212 
7213    Input Parameter:
7214 .  mat - the matrix
7215 
7216    Output Parameter:
7217 .  bs - block size
7218 
7219    Notes:
7220     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7221 
7222    If the block size has not been set yet this routine returns 1.
7223 
7224    Level: intermediate
7225 
7226 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()`
7227 @*/
7228 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7229 {
7230   PetscFunctionBegin;
7231   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7232   PetscValidIntPointer(bs,2);
7233   *bs = PetscAbs(mat->rmap->bs);
7234   PetscFunctionReturn(0);
7235 }
7236 
7237 /*@
7238    MatGetBlockSizes - Returns the matrix block row and column sizes.
7239 
7240    Not Collective
7241 
7242    Input Parameter:
7243 .  mat - the matrix
7244 
7245    Output Parameters:
7246 +  rbs - row block size
7247 -  cbs - column block size
7248 
7249    Notes:
7250     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7251     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7252 
7253    If a block size has not been set yet this routine returns 1.
7254 
7255    Level: intermediate
7256 
7257 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()`
7258 @*/
7259 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7260 {
7261   PetscFunctionBegin;
7262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7263   if (rbs) PetscValidIntPointer(rbs,2);
7264   if (cbs) PetscValidIntPointer(cbs,3);
7265   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7266   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7267   PetscFunctionReturn(0);
7268 }
7269 
7270 /*@
7271    MatSetBlockSize - Sets the matrix block size.
7272 
7273    Logically Collective on Mat
7274 
7275    Input Parameters:
7276 +  mat - the matrix
7277 -  bs - block size
7278 
7279    Notes:
7280     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7281     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7282 
7283     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7284     is compatible with the matrix local sizes.
7285 
7286    Level: intermediate
7287 
7288 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`
7289 @*/
7290 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7291 {
7292   PetscFunctionBegin;
7293   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7294   PetscValidLogicalCollectiveInt(mat,bs,2);
7295   PetscCall(MatSetBlockSizes(mat,bs,bs));
7296   PetscFunctionReturn(0);
7297 }
7298 
7299 typedef struct {
7300   PetscInt         n;
7301   IS               *is;
7302   Mat              *mat;
7303   PetscObjectState nonzerostate;
7304   Mat              C;
7305 } EnvelopeData;
7306 
7307 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata)
7308 {
7309   for (PetscInt i=0; i<edata->n; i++) {
7310     PetscCall(ISDestroy(&edata->is[i]));
7311   }
7312   PetscCall(PetscFree(edata->is));
7313   PetscCall(PetscFree(edata));
7314   return 0;
7315 }
7316 
7317 /*
7318    MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores
7319          the sizes of these blocks in the matrix. An individual block may lie over several processes.
7320 
7321    Collective on mat
7322 
7323    Input Parameter:
7324 .  mat - the matrix
7325 
7326    Notes:
7327      There can be zeros within the blocks
7328 
7329      The blocks can overlap between processes, including laying on more than two processes
7330 
7331 */
7332 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat)
7333 {
7334   PetscInt                    n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend;
7335   PetscInt                    *diag,*odiag,sc;
7336   VecScatter                  scatter;
7337   PetscScalar                 *seqv;
7338   const PetscScalar           *parv;
7339   const PetscInt              *ia,*ja;
7340   PetscBool                   set,flag,done;
7341   Mat                         AA = mat,A;
7342   MPI_Comm                    comm;
7343   PetscMPIInt                 rank,size,tag;
7344   MPI_Status                  status;
7345   PetscContainer              container;
7346   EnvelopeData                *edata;
7347   Vec                         seq,par;
7348   IS                          isglobal;
7349 
7350   PetscFunctionBegin;
7351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7352   PetscCall(MatIsSymmetricKnown(mat,&set,&flag));
7353   if (!set || !flag) {
7354     /* TOO: only needs nonzero structure of transpose */
7355     PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA));
7356     PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN));
7357   }
7358   PetscCall(MatAIJGetLocalMat(AA,&A));
7359   PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done));
7360   PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix");
7361 
7362   PetscCall(MatGetLocalSize(mat,&n,NULL));
7363   PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag));
7364   PetscCall(PetscObjectGetComm((PetscObject)mat,&comm));
7365   PetscCallMPI(MPI_Comm_size(comm,&size));
7366   PetscCallMPI(MPI_Comm_rank(comm,&rank));
7367 
7368   PetscCall(PetscMalloc2(n,&sizes,n,&starts));
7369 
7370   if (rank > 0) {
7371     PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status));
7372     PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status));
7373   }
7374   PetscCall(MatGetOwnershipRange(mat,&rstart,NULL));
7375   for (i=0; i<n; i++) {
7376     env = PetscMax(env,ja[ia[i+1]-1]);
7377     II = rstart + i;
7378     if (env == II) {
7379       starts[lblocks]  = tbs;
7380       sizes[lblocks++] = 1 + II - tbs;
7381       tbs = 1 + II;
7382     }
7383   }
7384   if (rank < size-1) {
7385     PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm));
7386     PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm));
7387   }
7388 
7389   PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done));
7390   if (!set || !flag) {
7391     PetscCall(MatDestroy(&AA));
7392   }
7393   PetscCall(MatDestroy(&A));
7394 
7395   PetscCall(PetscNew(&edata));
7396   PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate));
7397   edata->n = lblocks;
7398   /* create IS needed for extracting blocks from the original matrix */
7399   PetscCall(PetscMalloc1(lblocks,&edata->is));
7400   for (PetscInt i=0; i<lblocks; i++) {
7401     PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i]));
7402   }
7403 
7404   /* Create the resulting inverse matrix structure with preallocation information */
7405   PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C));
7406   PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N));
7407   PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat));
7408   PetscCall(MatSetType(edata->C,MATAIJ));
7409 
7410   /* Communicate the start and end of each row, from each block to the correct rank */
7411   /* TODO: Use PetscSF instead of VecScatter */
7412   for (PetscInt i=0; i<lblocks; i++) ln += sizes[i];
7413   PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq));
7414   PetscCall(VecGetArrayWrite(seq,&seqv));
7415   for (PetscInt i=0; i<lblocks; i++) {
7416     for (PetscInt j=0; j<sizes[i]; j++) {
7417       seqv[cnt]   = starts[i];
7418       seqv[cnt+1] = starts[i] + sizes[i];
7419       cnt += 2;
7420     }
7421   }
7422   PetscCall(VecRestoreArrayWrite(seq,&seqv));
7423   PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat)));
7424   sc -= cnt;
7425   PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par));
7426   PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal));
7427   PetscCall(VecScatterCreate(seq, NULL  ,par, isglobal,&scatter));
7428   PetscCall(ISDestroy(&isglobal));
7429   PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD));
7430   PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD));
7431   PetscCall(VecScatterDestroy(&scatter));
7432   PetscCall(VecDestroy(&seq));
7433   PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend));
7434   PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag));
7435   PetscCall(VecGetArrayRead(par,&parv));
7436   cnt = 0;
7437   PetscCall(MatGetSize(mat,NULL,&n));
7438   for (PetscInt i=0; i<mat->rmap->n; i++) {
7439     PetscInt start,end,d = 0,od = 0;
7440 
7441     start = (PetscInt)PetscRealPart(parv[cnt]);
7442     end   = (PetscInt)PetscRealPart(parv[cnt+1]);
7443     cnt  += 2;
7444 
7445     if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;}
7446     else if (start < cend) {od += n - cend; d += cend - start;}
7447     else od += n - start;
7448     if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;}
7449     else if (end < cend) {od -= n - cend; d -= cend - end;}
7450     else od -= n - end;
7451 
7452     odiag[i] = od;
7453     diag[i]  = d;
7454   }
7455   PetscCall(VecRestoreArrayRead(par,&parv));
7456   PetscCall(VecDestroy(&par));
7457   PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL));
7458   PetscCall(PetscFree2(diag,odiag));
7459   PetscCall(PetscFree2(sizes,starts));
7460 
7461   PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container));
7462   PetscCall(PetscContainerSetPointer(container,edata));
7463   PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy));
7464   PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container));
7465   PetscCall(PetscObjectDereference((PetscObject)container));
7466   PetscFunctionReturn(0);
7467 }
7468 
7469 /*@
7470   MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A
7471 
7472   Collective on Mat
7473 
7474   Input Parameters:
7475 . A - the matrix
7476 
7477   Output Parameters:
7478 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
7479 
7480   Notes:
7481      For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal.
7482 
7483   Level: advanced
7484 
7485 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal()
7486 @*/
7487 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C)
7488 {
7489   PetscContainer    container;
7490   EnvelopeData      *edata;
7491   PetscObjectState  nonzerostate;
7492 
7493   PetscFunctionBegin;
7494   PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container));
7495   if (!container) {
7496     PetscCall(MatComputeVariableBlockEnvelope(A));
7497     PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container));
7498   }
7499   PetscCall(PetscContainerGetPointer(container,(void**)&edata));
7500   PetscCall(MatGetNonzeroState(A,&nonzerostate));
7501   PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure");
7502   PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output");
7503 
7504   PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat));
7505   *C   = edata->C;
7506 
7507   for (PetscInt i=0; i<edata->n; i++) {
7508     Mat         D;
7509     PetscScalar *dvalues;
7510 
7511     PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D));
7512     PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE));
7513     PetscCall(MatSeqDenseInvert(D));
7514     PetscCall(MatDenseGetArray(D,&dvalues));
7515     PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES));
7516     PetscCall(MatDestroy(&D));
7517   }
7518   PetscCall(MatDestroySubMatrices(edata->n,&edata->mat));
7519   PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY));
7520   PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY));
7521   PetscFunctionReturn(0);
7522 }
7523 
7524 /*@
7525    MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size
7526 
7527    Logically Collective on Mat
7528 
7529    Input Parameters:
7530 +  mat - the matrix
7531 .  nblocks - the number of blocks on this process, each block can only exist on a single process
7532 -  bsizes - the block sizes
7533 
7534    Notes:
7535     Currently used by PCVPBJACOBI for AIJ matrices
7536 
7537     Each variable point-block set of degrees of freedom must live on a single MPI rank. That is a point block cannot straddle two MPI ranks.
7538 
7539    Level: intermediate
7540 
7541 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI`
7542 @*/
7543 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7544 {
7545   PetscInt       i,ncnt = 0, nlocal;
7546 
7547   PetscFunctionBegin;
7548   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7549   PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7550   PetscCall(MatGetLocalSize(mat,&nlocal,NULL));
7551   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7552   PetscCheck(ncnt == nlocal,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %" PetscInt_FMT " does not equal local size of matrix %" PetscInt_FMT,ncnt,nlocal);
7553   PetscCall(PetscFree(mat->bsizes));
7554   mat->nblocks = nblocks;
7555   PetscCall(PetscMalloc1(nblocks,&mat->bsizes));
7556   PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks));
7557   PetscFunctionReturn(0);
7558 }
7559 
7560 /*@C
7561    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7562 
7563    Logically Collective on Mat
7564 
7565    Input Parameter:
7566 .  mat - the matrix
7567 
7568    Output Parameters:
7569 +  nblocks - the number of blocks on this process
7570 -  bsizes - the block sizes
7571 
7572    Notes: Currently not supported from Fortran
7573 
7574    Level: intermediate
7575 
7576 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`
7577 @*/
7578 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7579 {
7580   PetscFunctionBegin;
7581   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7582   *nblocks = mat->nblocks;
7583   *bsizes  = mat->bsizes;
7584   PetscFunctionReturn(0);
7585 }
7586 
7587 /*@
7588    MatSetBlockSizes - Sets the matrix block row and column sizes.
7589 
7590    Logically Collective on Mat
7591 
7592    Input Parameters:
7593 +  mat - the matrix
7594 .  rbs - row block size
7595 -  cbs - column block size
7596 
7597    Notes:
7598     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7599     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7600     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7601 
7602     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7603     are compatible with the matrix local sizes.
7604 
7605     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7606 
7607    Level: intermediate
7608 
7609 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()`
7610 @*/
7611 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7612 {
7613   PetscFunctionBegin;
7614   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7615   PetscValidLogicalCollectiveInt(mat,rbs,2);
7616   PetscValidLogicalCollectiveInt(mat,cbs,3);
7617   if (mat->ops->setblocksizes) {
7618     PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs));
7619   }
7620   if (mat->rmap->refcnt) {
7621     ISLocalToGlobalMapping l2g = NULL;
7622     PetscLayout            nmap = NULL;
7623 
7624     PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap));
7625     if (mat->rmap->mapping) {
7626       PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g));
7627     }
7628     PetscCall(PetscLayoutDestroy(&mat->rmap));
7629     mat->rmap = nmap;
7630     mat->rmap->mapping = l2g;
7631   }
7632   if (mat->cmap->refcnt) {
7633     ISLocalToGlobalMapping l2g = NULL;
7634     PetscLayout            nmap = NULL;
7635 
7636     PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap));
7637     if (mat->cmap->mapping) {
7638       PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g));
7639     }
7640     PetscCall(PetscLayoutDestroy(&mat->cmap));
7641     mat->cmap = nmap;
7642     mat->cmap->mapping = l2g;
7643   }
7644   PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs));
7645   PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs));
7646   PetscFunctionReturn(0);
7647 }
7648 
7649 /*@
7650    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7651 
7652    Logically Collective on Mat
7653 
7654    Input Parameters:
7655 +  mat - the matrix
7656 .  fromRow - matrix from which to copy row block size
7657 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7658 
7659    Level: developer
7660 
7661 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`
7662 @*/
7663 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7664 {
7665   PetscFunctionBegin;
7666   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7667   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7668   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7669   if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs));
7670   if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs));
7671   PetscFunctionReturn(0);
7672 }
7673 
7674 /*@
7675    MatResidual - Default routine to calculate the residual.
7676 
7677    Collective on Mat
7678 
7679    Input Parameters:
7680 +  mat - the matrix
7681 .  b   - the right-hand-side
7682 -  x   - the approximate solution
7683 
7684    Output Parameter:
7685 .  r - location to store the residual
7686 
7687    Level: developer
7688 
7689 .seealso: `PCMGSetResidual()`
7690 @*/
7691 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7692 {
7693   PetscFunctionBegin;
7694   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7695   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7696   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7697   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7698   PetscValidType(mat,1);
7699   MatCheckPreallocated(mat,1);
7700   PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0));
7701   if (!mat->ops->residual) {
7702     PetscCall(MatMult(mat,x,r));
7703     PetscCall(VecAYPX(r,-1.0,b));
7704   } else {
7705     PetscCall((*mat->ops->residual)(mat,b,x,r));
7706   }
7707   PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0));
7708   PetscFunctionReturn(0);
7709 }
7710 
7711 /*@C
7712     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7713 
7714    Collective on Mat
7715 
7716     Input Parameters:
7717 +   mat - the matrix
7718 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7719 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7720 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7721                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7722                  always used.
7723 
7724     Output Parameters:
7725 +   n - number of rows in the (possibly compressed) matrix
7726 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7727 .   ja - the column indices
7728 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7729            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7730 
7731     Level: developer
7732 
7733     Notes:
7734     You CANNOT change any of the ia[] or ja[] values.
7735 
7736     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7737 
7738     Fortran Notes:
7739     In Fortran use
7740 $
7741 $      PetscInt ia(1), ja(1)
7742 $      PetscOffset iia, jja
7743 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7744 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7745 
7746      or
7747 $
7748 $    PetscInt, pointer :: ia(:),ja(:)
7749 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7750 $    ! Access the ith and jth entries via ia(i) and ja(j)
7751 
7752 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()`
7753 @*/
7754 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7755 {
7756   PetscFunctionBegin;
7757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7758   PetscValidType(mat,1);
7759   PetscValidIntPointer(n,5);
7760   if (ia) PetscValidPointer(ia,6);
7761   if (ja) PetscValidPointer(ja,7);
7762   PetscValidBoolPointer(done,8);
7763   MatCheckPreallocated(mat,1);
7764   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7765   else {
7766     *done = PETSC_TRUE;
7767     PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0));
7768     PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done));
7769     PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0));
7770   }
7771   PetscFunctionReturn(0);
7772 }
7773 
7774 /*@C
7775     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7776 
7777     Collective on Mat
7778 
7779     Input Parameters:
7780 +   mat - the matrix
7781 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7782 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7783                 symmetrized
7784 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7785                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7786                  always used.
7787 .   n - number of columns in the (possibly compressed) matrix
7788 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7789 -   ja - the row indices
7790 
7791     Output Parameters:
7792 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7793 
7794     Level: developer
7795 
7796 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()`
7797 @*/
7798 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7799 {
7800   PetscFunctionBegin;
7801   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7802   PetscValidType(mat,1);
7803   PetscValidIntPointer(n,5);
7804   if (ia) PetscValidPointer(ia,6);
7805   if (ja) PetscValidPointer(ja,7);
7806   PetscValidBoolPointer(done,8);
7807   MatCheckPreallocated(mat,1);
7808   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7809   else {
7810     *done = PETSC_TRUE;
7811     PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done));
7812   }
7813   PetscFunctionReturn(0);
7814 }
7815 
7816 /*@C
7817     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7818     MatGetRowIJ().
7819 
7820     Collective on Mat
7821 
7822     Input Parameters:
7823 +   mat - the matrix
7824 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7825 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7826                 symmetrized
7827 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7828                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7829                  always used.
7830 .   n - size of (possibly compressed) matrix
7831 .   ia - the row pointers
7832 -   ja - the column indices
7833 
7834     Output Parameters:
7835 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7836 
7837     Note:
7838     This routine zeros out n, ia, and ja. This is to prevent accidental
7839     us of the array after it has been restored. If you pass NULL, it will
7840     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7841 
7842     Level: developer
7843 
7844 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()`
7845 @*/
7846 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7847 {
7848   PetscFunctionBegin;
7849   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7850   PetscValidType(mat,1);
7851   if (ia) PetscValidPointer(ia,6);
7852   if (ja) PetscValidPointer(ja,7);
7853   PetscValidBoolPointer(done,8);
7854   MatCheckPreallocated(mat,1);
7855 
7856   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7857   else {
7858     *done = PETSC_TRUE;
7859     PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done));
7860     if (n)  *n = 0;
7861     if (ia) *ia = NULL;
7862     if (ja) *ja = NULL;
7863   }
7864   PetscFunctionReturn(0);
7865 }
7866 
7867 /*@C
7868     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7869     MatGetColumnIJ().
7870 
7871     Collective on Mat
7872 
7873     Input Parameters:
7874 +   mat - the matrix
7875 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7876 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7877                 symmetrized
7878 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7879                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7880                  always used.
7881 
7882     Output Parameters:
7883 +   n - size of (possibly compressed) matrix
7884 .   ia - the column pointers
7885 .   ja - the row indices
7886 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7887 
7888     Level: developer
7889 
7890 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`
7891 @*/
7892 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7893 {
7894   PetscFunctionBegin;
7895   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7896   PetscValidType(mat,1);
7897   if (ia) PetscValidPointer(ia,6);
7898   if (ja) PetscValidPointer(ja,7);
7899   PetscValidBoolPointer(done,8);
7900   MatCheckPreallocated(mat,1);
7901 
7902   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7903   else {
7904     *done = PETSC_TRUE;
7905     PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done));
7906     if (n)  *n = 0;
7907     if (ia) *ia = NULL;
7908     if (ja) *ja = NULL;
7909   }
7910   PetscFunctionReturn(0);
7911 }
7912 
7913 /*@C
7914     MatColoringPatch -Used inside matrix coloring routines that
7915     use MatGetRowIJ() and/or MatGetColumnIJ().
7916 
7917     Collective on Mat
7918 
7919     Input Parameters:
7920 +   mat - the matrix
7921 .   ncolors - max color value
7922 .   n   - number of entries in colorarray
7923 -   colorarray - array indicating color for each column
7924 
7925     Output Parameters:
7926 .   iscoloring - coloring generated using colorarray information
7927 
7928     Level: developer
7929 
7930 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()`
7931 
7932 @*/
7933 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7934 {
7935   PetscFunctionBegin;
7936   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7937   PetscValidType(mat,1);
7938   PetscValidIntPointer(colorarray,4);
7939   PetscValidPointer(iscoloring,5);
7940   MatCheckPreallocated(mat,1);
7941 
7942   if (!mat->ops->coloringpatch) {
7943     PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring));
7944   } else {
7945     PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring));
7946   }
7947   PetscFunctionReturn(0);
7948 }
7949 
7950 /*@
7951    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7952 
7953    Logically Collective on Mat
7954 
7955    Input Parameter:
7956 .  mat - the factored matrix to be reset
7957 
7958    Notes:
7959    This routine should be used only with factored matrices formed by in-place
7960    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7961    format).  This option can save memory, for example, when solving nonlinear
7962    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7963    ILU(0) preconditioner.
7964 
7965    Note that one can specify in-place ILU(0) factorization by calling
7966 .vb
7967      PCType(pc,PCILU);
7968      PCFactorSeUseInPlace(pc);
7969 .ve
7970    or by using the options -pc_type ilu -pc_factor_in_place
7971 
7972    In-place factorization ILU(0) can also be used as a local
7973    solver for the blocks within the block Jacobi or additive Schwarz
7974    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7975    for details on setting local solver options.
7976 
7977    Most users should employ the simplified KSP interface for linear solvers
7978    instead of working directly with matrix algebra routines such as this.
7979    See, e.g., KSPCreate().
7980 
7981    Level: developer
7982 
7983 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()`
7984 
7985 @*/
7986 PetscErrorCode MatSetUnfactored(Mat mat)
7987 {
7988   PetscFunctionBegin;
7989   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7990   PetscValidType(mat,1);
7991   MatCheckPreallocated(mat,1);
7992   mat->factortype = MAT_FACTOR_NONE;
7993   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7994   PetscCall((*mat->ops->setunfactored)(mat));
7995   PetscFunctionReturn(0);
7996 }
7997 
7998 /*MC
7999     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
8000 
8001     Synopsis:
8002     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
8003 
8004     Not collective
8005 
8006     Input Parameter:
8007 .   x - matrix
8008 
8009     Output Parameters:
8010 +   xx_v - the Fortran90 pointer to the array
8011 -   ierr - error code
8012 
8013     Example of Usage:
8014 .vb
8015       PetscScalar, pointer xx_v(:,:)
8016       ....
8017       call MatDenseGetArrayF90(x,xx_v,ierr)
8018       a = xx_v(3)
8019       call MatDenseRestoreArrayF90(x,xx_v,ierr)
8020 .ve
8021 
8022     Level: advanced
8023 
8024 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()`
8025 
8026 M*/
8027 
8028 /*MC
8029     MatDenseRestoreArrayF90 - Restores a matrix array that has been
8030     accessed with MatDenseGetArrayF90().
8031 
8032     Synopsis:
8033     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
8034 
8035     Not collective
8036 
8037     Input Parameters:
8038 +   x - matrix
8039 -   xx_v - the Fortran90 pointer to the array
8040 
8041     Output Parameter:
8042 .   ierr - error code
8043 
8044     Example of Usage:
8045 .vb
8046        PetscScalar, pointer xx_v(:,:)
8047        ....
8048        call MatDenseGetArrayF90(x,xx_v,ierr)
8049        a = xx_v(3)
8050        call MatDenseRestoreArrayF90(x,xx_v,ierr)
8051 .ve
8052 
8053     Level: advanced
8054 
8055 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()`
8056 
8057 M*/
8058 
8059 /*MC
8060     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
8061 
8062     Synopsis:
8063     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8064 
8065     Not collective
8066 
8067     Input Parameter:
8068 .   x - matrix
8069 
8070     Output Parameters:
8071 +   xx_v - the Fortran90 pointer to the array
8072 -   ierr - error code
8073 
8074     Example of Usage:
8075 .vb
8076       PetscScalar, pointer xx_v(:)
8077       ....
8078       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8079       a = xx_v(3)
8080       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8081 .ve
8082 
8083     Level: advanced
8084 
8085 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()`
8086 
8087 M*/
8088 
8089 /*MC
8090     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
8091     accessed with MatSeqAIJGetArrayF90().
8092 
8093     Synopsis:
8094     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8095 
8096     Not collective
8097 
8098     Input Parameters:
8099 +   x - matrix
8100 -   xx_v - the Fortran90 pointer to the array
8101 
8102     Output Parameter:
8103 .   ierr - error code
8104 
8105     Example of Usage:
8106 .vb
8107        PetscScalar, pointer xx_v(:)
8108        ....
8109        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8110        a = xx_v(3)
8111        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8112 .ve
8113 
8114     Level: advanced
8115 
8116 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()`
8117 
8118 M*/
8119 
8120 /*@
8121     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
8122                       as the original matrix.
8123 
8124     Collective on Mat
8125 
8126     Input Parameters:
8127 +   mat - the original matrix
8128 .   isrow - parallel IS containing the rows this processor should obtain
8129 .   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.
8130 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8131 
8132     Output Parameter:
8133 .   newmat - the new submatrix, of the same type as the old
8134 
8135     Level: advanced
8136 
8137     Notes:
8138     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
8139 
8140     Some matrix types place restrictions on the row and column indices, such
8141     as that they be sorted or that they be equal to each other.
8142 
8143     The index sets may not have duplicate entries.
8144 
8145       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8146    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8147    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8148    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8149    you are finished using it.
8150 
8151     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8152     the input matrix.
8153 
8154     If iscol is NULL then all columns are obtained (not supported in Fortran).
8155 
8156    Example usage:
8157    Consider the following 8x8 matrix with 34 non-zero values, that is
8158    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8159    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8160    as follows:
8161 
8162 .vb
8163             1  2  0  |  0  3  0  |  0  4
8164     Proc0   0  5  6  |  7  0  0  |  8  0
8165             9  0 10  | 11  0  0  | 12  0
8166     -------------------------------------
8167            13  0 14  | 15 16 17  |  0  0
8168     Proc1   0 18  0  | 19 20 21  |  0  0
8169             0  0  0  | 22 23  0  | 24  0
8170     -------------------------------------
8171     Proc2  25 26 27  |  0  0 28  | 29  0
8172            30  0  0  | 31 32 33  |  0 34
8173 .ve
8174 
8175     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8176 
8177 .vb
8178             2  0  |  0  3  0  |  0
8179     Proc0   5  6  |  7  0  0  |  8
8180     -------------------------------
8181     Proc1  18  0  | 19 20 21  |  0
8182     -------------------------------
8183     Proc2  26 27  |  0  0 28  | 29
8184             0  0  | 31 32 33  |  0
8185 .ve
8186 
8187 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()`
8188 @*/
8189 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8190 {
8191   PetscMPIInt    size;
8192   Mat            *local;
8193   IS             iscoltmp;
8194   PetscBool      flg;
8195 
8196   PetscFunctionBegin;
8197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8198   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8199   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8200   PetscValidPointer(newmat,5);
8201   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8202   PetscValidType(mat,1);
8203   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8204   PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8205 
8206   MatCheckPreallocated(mat,1);
8207   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
8208 
8209   if (!iscol || isrow == iscol) {
8210     PetscBool   stride;
8211     PetscMPIInt grabentirematrix = 0,grab;
8212     PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride));
8213     if (stride) {
8214       PetscInt first,step,n,rstart,rend;
8215       PetscCall(ISStrideGetInfo(isrow,&first,&step));
8216       if (step == 1) {
8217         PetscCall(MatGetOwnershipRange(mat,&rstart,&rend));
8218         if (rstart == first) {
8219           PetscCall(ISGetLocalSize(isrow,&n));
8220           if (n == rend-rstart) {
8221             grabentirematrix = 1;
8222           }
8223         }
8224       }
8225     }
8226     PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat)));
8227     if (grab) {
8228       PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n"));
8229       if (cll == MAT_INITIAL_MATRIX) {
8230         *newmat = mat;
8231         PetscCall(PetscObjectReference((PetscObject)mat));
8232       }
8233       PetscFunctionReturn(0);
8234     }
8235   }
8236 
8237   if (!iscol) {
8238     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp));
8239   } else {
8240     iscoltmp = iscol;
8241   }
8242 
8243   /* if original matrix is on just one processor then use submatrix generated */
8244   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8245     PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat));
8246     goto setproperties;
8247   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8248     PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local));
8249     *newmat = *local;
8250     PetscCall(PetscFree(local));
8251     goto setproperties;
8252   } else if (!mat->ops->createsubmatrix) {
8253     /* Create a new matrix type that implements the operation using the full matrix */
8254     PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0));
8255     switch (cll) {
8256     case MAT_INITIAL_MATRIX:
8257       PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat));
8258       break;
8259     case MAT_REUSE_MATRIX:
8260       PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp));
8261       break;
8262     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8263     }
8264     PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0));
8265     goto setproperties;
8266   }
8267 
8268   PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8269   PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0));
8270   PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat));
8271   PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0));
8272 
8273 setproperties:
8274   PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg));
8275   if (flg) {
8276     PetscCall(MatPropagateSymmetryOptions(mat,*newmat));
8277   }
8278   if (!iscol) PetscCall(ISDestroy(&iscoltmp));
8279   if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat));
8280   PetscFunctionReturn(0);
8281 }
8282 
8283 /*@
8284    MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
8285 
8286    Not Collective
8287 
8288    Input Parameters:
8289 +  A - the matrix we wish to propagate options from
8290 -  B - the matrix we wish to propagate options to
8291 
8292    Level: beginner
8293 
8294    Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
8295 
8296 .seealso: `MatSetOption()`
8297 @*/
8298 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
8299 {
8300   PetscFunctionBegin;
8301   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8302   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8303   if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
8304     PetscCall(MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal));
8305   }
8306   if (A->structurally_symmetric_set) {
8307     PetscCall(MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric));
8308   }
8309   if (A->hermitian_set) {
8310     PetscCall(MatSetOption(B,MAT_HERMITIAN,A->hermitian));
8311   }
8312   if (A->spd_set) {
8313     PetscCall(MatSetOption(B,MAT_SPD,A->spd));
8314   }
8315   if (A->symmetric_set) {
8316     PetscCall(MatSetOption(B,MAT_SYMMETRIC,A->symmetric));
8317   }
8318   PetscFunctionReturn(0);
8319 }
8320 
8321 /*@
8322    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8323    used during the assembly process to store values that belong to
8324    other processors.
8325 
8326    Not Collective
8327 
8328    Input Parameters:
8329 +  mat   - the matrix
8330 .  size  - the initial size of the stash.
8331 -  bsize - the initial size of the block-stash(if used).
8332 
8333    Options Database Keys:
8334 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8335 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8336 
8337    Level: intermediate
8338 
8339    Notes:
8340      The block-stash is used for values set with MatSetValuesBlocked() while
8341      the stash is used for values set with MatSetValues()
8342 
8343      Run with the option -info and look for output of the form
8344      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8345      to determine the appropriate value, MM, to use for size and
8346      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8347      to determine the value, BMM to use for bsize
8348 
8349 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()`
8350 
8351 @*/
8352 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8353 {
8354   PetscFunctionBegin;
8355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8356   PetscValidType(mat,1);
8357   PetscCall(MatStashSetInitialSize_Private(&mat->stash,size));
8358   PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize));
8359   PetscFunctionReturn(0);
8360 }
8361 
8362 /*@
8363    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8364      the matrix
8365 
8366    Neighbor-wise Collective on Mat
8367 
8368    Input Parameters:
8369 +  mat   - the matrix
8370 .  x,y - the vectors
8371 -  w - where the result is stored
8372 
8373    Level: intermediate
8374 
8375    Notes:
8376     w may be the same vector as y.
8377 
8378     This allows one to use either the restriction or interpolation (its transpose)
8379     matrix to do the interpolation
8380 
8381 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`
8382 
8383 @*/
8384 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8385 {
8386   PetscInt       M,N,Ny;
8387 
8388   PetscFunctionBegin;
8389   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8390   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8391   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8392   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8393   PetscCall(MatGetSize(A,&M,&N));
8394   PetscCall(VecGetSize(y,&Ny));
8395   if (M == Ny) {
8396     PetscCall(MatMultAdd(A,x,y,w));
8397   } else {
8398     PetscCall(MatMultTransposeAdd(A,x,y,w));
8399   }
8400   PetscFunctionReturn(0);
8401 }
8402 
8403 /*@
8404    MatInterpolate - y = A*x or A'*x depending on the shape of
8405      the matrix
8406 
8407    Neighbor-wise Collective on Mat
8408 
8409    Input Parameters:
8410 +  mat   - the matrix
8411 -  x,y - the vectors
8412 
8413    Level: intermediate
8414 
8415    Notes:
8416     This allows one to use either the restriction or interpolation (its transpose)
8417     matrix to do the interpolation
8418 
8419 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`
8420 
8421 @*/
8422 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8423 {
8424   PetscInt       M,N,Ny;
8425 
8426   PetscFunctionBegin;
8427   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8428   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8429   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8430   PetscCall(MatGetSize(A,&M,&N));
8431   PetscCall(VecGetSize(y,&Ny));
8432   if (M == Ny) {
8433     PetscCall(MatMult(A,x,y));
8434   } else {
8435     PetscCall(MatMultTranspose(A,x,y));
8436   }
8437   PetscFunctionReturn(0);
8438 }
8439 
8440 /*@
8441    MatRestrict - y = A*x or A'*x
8442 
8443    Neighbor-wise Collective on Mat
8444 
8445    Input Parameters:
8446 +  mat   - the matrix
8447 -  x,y - the vectors
8448 
8449    Level: intermediate
8450 
8451    Notes:
8452     This allows one to use either the restriction or interpolation (its transpose)
8453     matrix to do the restriction
8454 
8455 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()`
8456 
8457 @*/
8458 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8459 {
8460   PetscInt       M,N,Ny;
8461 
8462   PetscFunctionBegin;
8463   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8464   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8465   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8466   PetscCall(MatGetSize(A,&M,&N));
8467   PetscCall(VecGetSize(y,&Ny));
8468   if (M == Ny) {
8469     PetscCall(MatMult(A,x,y));
8470   } else {
8471     PetscCall(MatMultTranspose(A,x,y));
8472   }
8473   PetscFunctionReturn(0);
8474 }
8475 
8476 /*@
8477    MatMatInterpolateAdd - Y = W + A*X or W + A'*X
8478 
8479    Neighbor-wise Collective on Mat
8480 
8481    Input Parameters:
8482 +  mat   - the matrix
8483 -  w, x - the input dense matrices
8484 
8485    Output Parameters:
8486 .  y - the output dense matrix
8487 
8488    Level: intermediate
8489 
8490    Notes:
8491     This allows one to use either the restriction or interpolation (its transpose)
8492     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8493     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8494 
8495 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()`
8496 
8497 @*/
8498 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y)
8499 {
8500   PetscInt       M,N,Mx,Nx,Mo,My = 0,Ny = 0;
8501   PetscBool      trans = PETSC_TRUE;
8502   MatReuse       reuse = MAT_INITIAL_MATRIX;
8503 
8504   PetscFunctionBegin;
8505   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8506   PetscValidHeaderSpecific(x,MAT_CLASSID,2);
8507   PetscValidType(x,2);
8508   if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3);
8509   if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4);
8510   PetscCall(MatGetSize(A,&M,&N));
8511   PetscCall(MatGetSize(x,&Mx,&Nx));
8512   if (N == Mx) trans = PETSC_FALSE;
8513   else PetscCheck(M == Mx,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx);
8514   Mo = trans ? N : M;
8515   if (*y) {
8516     PetscCall(MatGetSize(*y,&My,&Ny));
8517     if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; }
8518     else {
8519       PetscCheck(w || *y != w,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot reuse y and w, size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT ", Y %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx,My,Ny);
8520       PetscCall(MatDestroy(y));
8521     }
8522   }
8523 
8524   if (w && *y == w) { /* this is to minimize changes in PCMG */
8525     PetscBool flg;
8526 
8527     PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w));
8528     if (w) {
8529       PetscInt My,Ny,Mw,Nw;
8530 
8531       PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg));
8532       PetscCall(MatGetSize(*y,&My,&Ny));
8533       PetscCall(MatGetSize(w,&Mw,&Nw));
8534       if (!flg || My != Mw || Ny != Nw) w = NULL;
8535     }
8536     if (!w) {
8537       PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w));
8538       PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w));
8539       PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w));
8540       PetscCall(PetscObjectDereference((PetscObject)w));
8541     } else {
8542       PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN));
8543     }
8544   }
8545   if (!trans) {
8546     PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y));
8547   } else {
8548     PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y));
8549   }
8550   if (w) {
8551     PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN));
8552   }
8553   PetscFunctionReturn(0);
8554 }
8555 
8556 /*@
8557    MatMatInterpolate - Y = A*X or A'*X
8558 
8559    Neighbor-wise Collective on Mat
8560 
8561    Input Parameters:
8562 +  mat   - the matrix
8563 -  x - the input dense matrix
8564 
8565    Output Parameters:
8566 .  y - the output dense matrix
8567 
8568    Level: intermediate
8569 
8570    Notes:
8571     This allows one to use either the restriction or interpolation (its transpose)
8572     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8573     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8574 
8575 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()`
8576 
8577 @*/
8578 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y)
8579 {
8580   PetscFunctionBegin;
8581   PetscCall(MatMatInterpolateAdd(A,x,NULL,y));
8582   PetscFunctionReturn(0);
8583 }
8584 
8585 /*@
8586    MatMatRestrict - Y = A*X or A'*X
8587 
8588    Neighbor-wise Collective on Mat
8589 
8590    Input Parameters:
8591 +  mat   - the matrix
8592 -  x - the input dense matrix
8593 
8594    Output Parameters:
8595 .  y - the output dense matrix
8596 
8597    Level: intermediate
8598 
8599    Notes:
8600     This allows one to use either the restriction or interpolation (its transpose)
8601     matrix to do the restriction. y matrix can be reused if already created with the proper sizes,
8602     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8603 
8604 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()`
8605 @*/
8606 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y)
8607 {
8608   PetscFunctionBegin;
8609   PetscCall(MatMatInterpolateAdd(A,x,NULL,y));
8610   PetscFunctionReturn(0);
8611 }
8612 
8613 /*@
8614    MatGetNullSpace - retrieves the null space of a matrix.
8615 
8616    Logically Collective on Mat
8617 
8618    Input Parameters:
8619 +  mat - the matrix
8620 -  nullsp - the null space object
8621 
8622    Level: developer
8623 
8624 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()`
8625 @*/
8626 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8627 {
8628   PetscFunctionBegin;
8629   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8630   PetscValidPointer(nullsp,2);
8631   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8632   PetscFunctionReturn(0);
8633 }
8634 
8635 /*@
8636    MatSetNullSpace - attaches a null space to a matrix.
8637 
8638    Logically Collective on Mat
8639 
8640    Input Parameters:
8641 +  mat - the matrix
8642 -  nullsp - the null space object
8643 
8644    Level: advanced
8645 
8646    Notes:
8647       This null space is used by the KSP linear solvers to solve singular systems.
8648 
8649       Overwrites any previous null space that may have been attached. You can remove the null space from the matrix object by calling this routine with an nullsp of NULL
8650 
8651       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) the KSP residuals will not converge to
8652       to zero but the linear system will still be solved in a least squares sense.
8653 
8654       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8655    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).
8656    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
8657    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
8658    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).
8659    This  \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix.
8660 
8661     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
8662     routine also automatically calls MatSetTransposeNullSpace().
8663 
8664     The user should call `MatNullSpaceDestroy()`.
8665 
8666 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`,
8667           `KSPSetPCSide()`
8668 @*/
8669 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8670 {
8671   PetscFunctionBegin;
8672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8673   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8674   if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp));
8675   PetscCall(MatNullSpaceDestroy(&mat->nullsp));
8676   mat->nullsp = nullsp;
8677   if (mat->symmetric_set && mat->symmetric) {
8678     PetscCall(MatSetTransposeNullSpace(mat,nullsp));
8679   }
8680   PetscFunctionReturn(0);
8681 }
8682 
8683 /*@
8684    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8685 
8686    Logically Collective on Mat
8687 
8688    Input Parameters:
8689 +  mat - the matrix
8690 -  nullsp - the null space object
8691 
8692    Level: developer
8693 
8694 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()`
8695 @*/
8696 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8697 {
8698   PetscFunctionBegin;
8699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8700   PetscValidType(mat,1);
8701   PetscValidPointer(nullsp,2);
8702   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8703   PetscFunctionReturn(0);
8704 }
8705 
8706 /*@
8707    MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix
8708 
8709    Logically Collective on Mat
8710 
8711    Input Parameters:
8712 +  mat - the matrix
8713 -  nullsp - the null space object
8714 
8715    Level: advanced
8716 
8717    Notes:
8718       This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning.
8719 
8720       See MatSetNullSpace()
8721 
8722 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()`
8723 @*/
8724 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8725 {
8726   PetscFunctionBegin;
8727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8728   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8729   if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp));
8730   PetscCall(MatNullSpaceDestroy(&mat->transnullsp));
8731   mat->transnullsp = nullsp;
8732   PetscFunctionReturn(0);
8733 }
8734 
8735 /*@
8736    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8737         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8738 
8739    Logically Collective on Mat
8740 
8741    Input Parameters:
8742 +  mat - the matrix
8743 -  nullsp - the null space object
8744 
8745    Level: advanced
8746 
8747    Notes:
8748       Overwrites any previous near null space that may have been attached
8749 
8750       You can remove the null space by calling this routine with an nullsp of NULL
8751 
8752 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()`
8753 @*/
8754 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8755 {
8756   PetscFunctionBegin;
8757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8758   PetscValidType(mat,1);
8759   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8760   MatCheckPreallocated(mat,1);
8761   if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp));
8762   PetscCall(MatNullSpaceDestroy(&mat->nearnullsp));
8763   mat->nearnullsp = nullsp;
8764   PetscFunctionReturn(0);
8765 }
8766 
8767 /*@
8768    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8769 
8770    Not Collective
8771 
8772    Input Parameter:
8773 .  mat - the matrix
8774 
8775    Output Parameter:
8776 .  nullsp - the null space object, NULL if not set
8777 
8778    Level: developer
8779 
8780 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()`
8781 @*/
8782 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8783 {
8784   PetscFunctionBegin;
8785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8786   PetscValidType(mat,1);
8787   PetscValidPointer(nullsp,2);
8788   MatCheckPreallocated(mat,1);
8789   *nullsp = mat->nearnullsp;
8790   PetscFunctionReturn(0);
8791 }
8792 
8793 /*@C
8794    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8795 
8796    Collective on Mat
8797 
8798    Input Parameters:
8799 +  mat - the matrix
8800 .  row - row/column permutation
8801 .  fill - expected fill factor >= 1.0
8802 -  level - level of fill, for ICC(k)
8803 
8804    Notes:
8805    Probably really in-place only when level of fill is zero, otherwise allocates
8806    new space to store factored matrix and deletes previous memory.
8807 
8808    Most users should employ the simplified KSP interface for linear solvers
8809    instead of working directly with matrix algebra routines such as this.
8810    See, e.g., KSPCreate().
8811 
8812    Level: developer
8813 
8814 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`
8815 
8816     Developer Note: fortran interface is not autogenerated as the f90
8817     interface definition cannot be generated correctly [due to MatFactorInfo]
8818 
8819 @*/
8820 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8821 {
8822   PetscFunctionBegin;
8823   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8824   PetscValidType(mat,1);
8825   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8826   PetscValidPointer(info,3);
8827   PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8828   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8829   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8830   PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8831   MatCheckPreallocated(mat,1);
8832   PetscCall((*mat->ops->iccfactor)(mat,row,info));
8833   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
8834   PetscFunctionReturn(0);
8835 }
8836 
8837 /*@
8838    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8839          ghosted ones.
8840 
8841    Not Collective
8842 
8843    Input Parameters:
8844 +  mat - the matrix
8845 -  diag - the diagonal values, including ghost ones
8846 
8847    Level: developer
8848 
8849    Notes:
8850     Works only for MPIAIJ and MPIBAIJ matrices
8851 
8852 .seealso: `MatDiagonalScale()`
8853 @*/
8854 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8855 {
8856   PetscMPIInt    size;
8857 
8858   PetscFunctionBegin;
8859   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8860   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8861   PetscValidType(mat,1);
8862 
8863   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8864   PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0));
8865   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
8866   if (size == 1) {
8867     PetscInt n,m;
8868     PetscCall(VecGetSize(diag,&n));
8869     PetscCall(MatGetSize(mat,NULL,&m));
8870     if (m == n) {
8871       PetscCall(MatDiagonalScale(mat,NULL,diag));
8872     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8873   } else {
8874     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8875   }
8876   PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0));
8877   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
8878   PetscFunctionReturn(0);
8879 }
8880 
8881 /*@
8882    MatGetInertia - Gets the inertia from a factored matrix
8883 
8884    Collective on Mat
8885 
8886    Input Parameter:
8887 .  mat - the matrix
8888 
8889    Output Parameters:
8890 +   nneg - number of negative eigenvalues
8891 .   nzero - number of zero eigenvalues
8892 -   npos - number of positive eigenvalues
8893 
8894    Level: advanced
8895 
8896    Notes:
8897     Matrix must have been factored by MatCholeskyFactor()
8898 
8899 @*/
8900 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8901 {
8902   PetscFunctionBegin;
8903   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8904   PetscValidType(mat,1);
8905   PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8906   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8907   PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8908   PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos));
8909   PetscFunctionReturn(0);
8910 }
8911 
8912 /* ----------------------------------------------------------------*/
8913 /*@C
8914    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8915 
8916    Neighbor-wise Collective on Mats
8917 
8918    Input Parameters:
8919 +  mat - the factored matrix
8920 -  b - the right-hand-side vectors
8921 
8922    Output Parameter:
8923 .  x - the result vectors
8924 
8925    Notes:
8926    The vectors b and x cannot be the same.  I.e., one cannot
8927    call MatSolves(A,x,x).
8928 
8929    Notes:
8930    Most users should employ the simplified KSP interface for linear solvers
8931    instead of working directly with matrix algebra routines such as this.
8932    See, e.g., KSPCreate().
8933 
8934    Level: developer
8935 
8936 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()`
8937 @*/
8938 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8939 {
8940   PetscFunctionBegin;
8941   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8942   PetscValidType(mat,1);
8943   PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8944   PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8945   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8946 
8947   PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8948   MatCheckPreallocated(mat,1);
8949   PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0));
8950   PetscCall((*mat->ops->solves)(mat,b,x));
8951   PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0));
8952   PetscFunctionReturn(0);
8953 }
8954 
8955 /*@
8956    MatIsSymmetric - Test whether a matrix is symmetric
8957 
8958    Collective on Mat
8959 
8960    Input Parameters:
8961 +  A - the matrix to test
8962 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8963 
8964    Output Parameters:
8965 .  flg - the result
8966 
8967    Notes:
8968     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8969 
8970    Level: intermediate
8971 
8972 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()`
8973 @*/
8974 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8975 {
8976   PetscFunctionBegin;
8977   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8978   PetscValidBoolPointer(flg,3);
8979 
8980   if (!A->symmetric_set) {
8981     if (!A->ops->issymmetric) {
8982       MatType mattype;
8983       PetscCall(MatGetType(A,&mattype));
8984       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8985     }
8986     PetscCall((*A->ops->issymmetric)(A,tol,flg));
8987     if (!tol) {
8988       PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg));
8989     }
8990   } else if (A->symmetric) {
8991     *flg = PETSC_TRUE;
8992   } else if (!tol) {
8993     *flg = PETSC_FALSE;
8994   } else {
8995     if (!A->ops->issymmetric) {
8996       MatType mattype;
8997       PetscCall(MatGetType(A,&mattype));
8998       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8999     }
9000     PetscCall((*A->ops->issymmetric)(A,tol,flg));
9001   }
9002   PetscFunctionReturn(0);
9003 }
9004 
9005 /*@
9006    MatIsHermitian - Test whether a matrix is Hermitian
9007 
9008    Collective on Mat
9009 
9010    Input Parameters:
9011 +  A - the matrix to test
9012 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
9013 
9014    Output Parameters:
9015 .  flg - the result
9016 
9017    Level: intermediate
9018 
9019 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`,
9020           `MatIsSymmetricKnown()`, `MatIsSymmetric()`
9021 @*/
9022 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
9023 {
9024   PetscFunctionBegin;
9025   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9026   PetscValidBoolPointer(flg,3);
9027 
9028   if (!A->hermitian_set) {
9029     if (!A->ops->ishermitian) {
9030       MatType mattype;
9031       PetscCall(MatGetType(A,&mattype));
9032       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9033     }
9034     PetscCall((*A->ops->ishermitian)(A,tol,flg));
9035     if (!tol) {
9036       PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg));
9037     }
9038   } else if (A->hermitian) {
9039     *flg = PETSC_TRUE;
9040   } else if (!tol) {
9041     *flg = PETSC_FALSE;
9042   } else {
9043     if (!A->ops->ishermitian) {
9044       MatType mattype;
9045       PetscCall(MatGetType(A,&mattype));
9046       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9047     }
9048     PetscCall((*A->ops->ishermitian)(A,tol,flg));
9049   }
9050   PetscFunctionReturn(0);
9051 }
9052 
9053 /*@
9054    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
9055 
9056    Not Collective
9057 
9058    Input Parameter:
9059 .  A - the matrix to check
9060 
9061    Output Parameters:
9062 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
9063 -  flg - the result
9064 
9065    Level: advanced
9066 
9067    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
9068          if you want it explicitly checked
9069 
9070 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`
9071 @*/
9072 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
9073 {
9074   PetscFunctionBegin;
9075   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9076   PetscValidBoolPointer(set,2);
9077   PetscValidBoolPointer(flg,3);
9078   if (A->symmetric_set) {
9079     *set = PETSC_TRUE;
9080     *flg = A->symmetric;
9081   } else {
9082     *set = PETSC_FALSE;
9083   }
9084   PetscFunctionReturn(0);
9085 }
9086 
9087 /*@
9088    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
9089 
9090    Not Collective
9091 
9092    Input Parameter:
9093 .  A - the matrix to check
9094 
9095    Output Parameters:
9096 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
9097 -  flg - the result
9098 
9099    Level: advanced
9100 
9101    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
9102          if you want it explicitly checked
9103 
9104 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`
9105 @*/
9106 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
9107 {
9108   PetscFunctionBegin;
9109   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9110   PetscValidBoolPointer(set,2);
9111   PetscValidBoolPointer(flg,3);
9112   if (A->hermitian_set) {
9113     *set = PETSC_TRUE;
9114     *flg = A->hermitian;
9115   } else {
9116     *set = PETSC_FALSE;
9117   }
9118   PetscFunctionReturn(0);
9119 }
9120 
9121 /*@
9122    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
9123 
9124    Collective on Mat
9125 
9126    Input Parameter:
9127 .  A - the matrix to test
9128 
9129    Output Parameters:
9130 .  flg - the result
9131 
9132    Level: intermediate
9133 
9134 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`
9135 @*/
9136 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
9137 {
9138   PetscFunctionBegin;
9139   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9140   PetscValidBoolPointer(flg,2);
9141   if (!A->structurally_symmetric_set) {
9142     PetscCheck(A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name);
9143     PetscCall((*A->ops->isstructurallysymmetric)(A,flg));
9144     PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg));
9145   } else *flg = A->structurally_symmetric;
9146   PetscFunctionReturn(0);
9147 }
9148 
9149 /*@
9150    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
9151        to be communicated to other processors during the MatAssemblyBegin/End() process
9152 
9153     Not collective
9154 
9155    Input Parameter:
9156 .   vec - the vector
9157 
9158    Output Parameters:
9159 +   nstash   - the size of the stash
9160 .   reallocs - the number of additional mallocs incurred.
9161 .   bnstash   - the size of the block stash
9162 -   breallocs - the number of additional mallocs incurred.in the block stash
9163 
9164    Level: advanced
9165 
9166 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()`
9167 
9168 @*/
9169 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
9170 {
9171   PetscFunctionBegin;
9172   PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs));
9173   PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs));
9174   PetscFunctionReturn(0);
9175 }
9176 
9177 /*@C
9178    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
9179      parallel layout
9180 
9181    Collective on Mat
9182 
9183    Input Parameter:
9184 .  mat - the matrix
9185 
9186    Output Parameters:
9187 +   right - (optional) vector that the matrix can be multiplied against
9188 -   left - (optional) vector that the matrix vector product can be stored in
9189 
9190    Notes:
9191     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().
9192 
9193   Notes:
9194     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
9195 
9196   Level: advanced
9197 
9198 .seealso: `MatCreate()`, `VecDestroy()`
9199 @*/
9200 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
9201 {
9202   PetscFunctionBegin;
9203   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9204   PetscValidType(mat,1);
9205   if (mat->ops->getvecs) {
9206     PetscCall((*mat->ops->getvecs)(mat,right,left));
9207   } else {
9208     PetscInt rbs,cbs;
9209     PetscCall(MatGetBlockSizes(mat,&rbs,&cbs));
9210     if (right) {
9211       PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9212       PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right));
9213       PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE));
9214       PetscCall(VecSetBlockSize(*right,cbs));
9215       PetscCall(VecSetType(*right,mat->defaultvectype));
9216 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
9217       if (mat->boundtocpu && mat->bindingpropagates) {
9218         PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE));
9219         PetscCall(VecBindToCPU(*right,PETSC_TRUE));
9220       }
9221 #endif
9222       PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map));
9223     }
9224     if (left) {
9225       PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9226       PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left));
9227       PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE));
9228       PetscCall(VecSetBlockSize(*left,rbs));
9229       PetscCall(VecSetType(*left,mat->defaultvectype));
9230 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
9231       if (mat->boundtocpu && mat->bindingpropagates) {
9232         PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE));
9233         PetscCall(VecBindToCPU(*left,PETSC_TRUE));
9234       }
9235 #endif
9236       PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map));
9237     }
9238   }
9239   PetscFunctionReturn(0);
9240 }
9241 
9242 /*@C
9243    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9244      with default values.
9245 
9246    Not Collective
9247 
9248    Input Parameters:
9249 .    info - the MatFactorInfo data structure
9250 
9251    Notes:
9252     The solvers are generally used through the KSP and PC objects, for example
9253           PCLU, PCILU, PCCHOLESKY, PCICC
9254 
9255    Level: developer
9256 
9257 .seealso: `MatFactorInfo`
9258 
9259     Developer Note: fortran interface is not autogenerated as the f90
9260     interface definition cannot be generated correctly [due to MatFactorInfo]
9261 
9262 @*/
9263 
9264 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9265 {
9266   PetscFunctionBegin;
9267   PetscCall(PetscMemzero(info,sizeof(MatFactorInfo)));
9268   PetscFunctionReturn(0);
9269 }
9270 
9271 /*@
9272    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9273 
9274    Collective on Mat
9275 
9276    Input Parameters:
9277 +  mat - the factored matrix
9278 -  is - the index set defining the Schur indices (0-based)
9279 
9280    Notes:
9281     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9282 
9283    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9284 
9285    Level: developer
9286 
9287 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`,
9288           `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()`
9289 
9290 @*/
9291 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9292 {
9293   PetscErrorCode (*f)(Mat,IS);
9294 
9295   PetscFunctionBegin;
9296   PetscValidType(mat,1);
9297   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9298   PetscValidType(is,2);
9299   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9300   PetscCheckSameComm(mat,1,is,2);
9301   PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9302   PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f));
9303   PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
9304   PetscCall(MatDestroy(&mat->schur));
9305   PetscCall((*f)(mat,is));
9306   PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9307   PetscFunctionReturn(0);
9308 }
9309 
9310 /*@
9311   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9312 
9313    Logically Collective on Mat
9314 
9315    Input Parameters:
9316 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9317 .  S - location where to return the Schur complement, can be NULL
9318 -  status - the status of the Schur complement matrix, can be NULL
9319 
9320    Notes:
9321    You must call MatFactorSetSchurIS() before calling this routine.
9322 
9323    The routine provides a copy of the Schur matrix stored within the solver data structures.
9324    The caller must destroy the object when it is no longer needed.
9325    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9326 
9327    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)
9328 
9329    Developer Notes:
9330     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9331    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9332 
9333    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9334 
9335    Level: advanced
9336 
9337    References:
9338 
9339 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus`
9340 @*/
9341 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9342 {
9343   PetscFunctionBegin;
9344   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9345   if (S) PetscValidPointer(S,2);
9346   if (status) PetscValidPointer(status,3);
9347   if (S) {
9348     PetscErrorCode (*f)(Mat,Mat*);
9349 
9350     PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f));
9351     if (f) {
9352       PetscCall((*f)(F,S));
9353     } else {
9354       PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S));
9355     }
9356   }
9357   if (status) *status = F->schur_status;
9358   PetscFunctionReturn(0);
9359 }
9360 
9361 /*@
9362   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9363 
9364    Logically Collective on Mat
9365 
9366    Input Parameters:
9367 +  F - the factored matrix obtained by calling MatGetFactor()
9368 .  *S - location where to return the Schur complement, can be NULL
9369 -  status - the status of the Schur complement matrix, can be NULL
9370 
9371    Notes:
9372    You must call MatFactorSetSchurIS() before calling this routine.
9373 
9374    Schur complement mode is currently implemented for sequential matrices.
9375    The routine returns a the Schur Complement stored within the data strutures of the solver.
9376    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9377    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9378 
9379    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9380 
9381    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9382 
9383    Level: advanced
9384 
9385    References:
9386 
9387 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus`
9388 @*/
9389 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9390 {
9391   PetscFunctionBegin;
9392   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9393   if (S) PetscValidPointer(S,2);
9394   if (status) PetscValidPointer(status,3);
9395   if (S) *S = F->schur;
9396   if (status) *status = F->schur_status;
9397   PetscFunctionReturn(0);
9398 }
9399 
9400 /*@
9401   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9402 
9403    Logically Collective on Mat
9404 
9405    Input Parameters:
9406 +  F - the factored matrix obtained by calling MatGetFactor()
9407 .  *S - location where the Schur complement is stored
9408 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9409 
9410    Notes:
9411 
9412    Level: advanced
9413 
9414    References:
9415 
9416 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus`
9417 @*/
9418 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9419 {
9420   PetscFunctionBegin;
9421   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9422   if (S) {
9423     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9424     *S = NULL;
9425   }
9426   F->schur_status = status;
9427   PetscCall(MatFactorUpdateSchurStatus_Private(F));
9428   PetscFunctionReturn(0);
9429 }
9430 
9431 /*@
9432   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9433 
9434    Logically Collective on Mat
9435 
9436    Input Parameters:
9437 +  F - the factored matrix obtained by calling MatGetFactor()
9438 .  rhs - location where the right hand side of the Schur complement system is stored
9439 -  sol - location where the solution of the Schur complement system has to be returned
9440 
9441    Notes:
9442    The sizes of the vectors should match the size of the Schur complement
9443 
9444    Must be called after MatFactorSetSchurIS()
9445 
9446    Level: advanced
9447 
9448    References:
9449 
9450 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()`
9451 @*/
9452 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9453 {
9454   PetscFunctionBegin;
9455   PetscValidType(F,1);
9456   PetscValidType(rhs,2);
9457   PetscValidType(sol,3);
9458   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9459   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9460   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9461   PetscCheckSameComm(F,1,rhs,2);
9462   PetscCheckSameComm(F,1,sol,3);
9463   PetscCall(MatFactorFactorizeSchurComplement(F));
9464   switch (F->schur_status) {
9465   case MAT_FACTOR_SCHUR_FACTORED:
9466     PetscCall(MatSolveTranspose(F->schur,rhs,sol));
9467     break;
9468   case MAT_FACTOR_SCHUR_INVERTED:
9469     PetscCall(MatMultTranspose(F->schur,rhs,sol));
9470     break;
9471   default:
9472     SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status);
9473   }
9474   PetscFunctionReturn(0);
9475 }
9476 
9477 /*@
9478   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9479 
9480    Logically Collective on Mat
9481 
9482    Input Parameters:
9483 +  F - the factored matrix obtained by calling MatGetFactor()
9484 .  rhs - location where the right hand side of the Schur complement system is stored
9485 -  sol - location where the solution of the Schur complement system has to be returned
9486 
9487    Notes:
9488    The sizes of the vectors should match the size of the Schur complement
9489 
9490    Must be called after MatFactorSetSchurIS()
9491 
9492    Level: advanced
9493 
9494    References:
9495 
9496 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()`
9497 @*/
9498 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9499 {
9500   PetscFunctionBegin;
9501   PetscValidType(F,1);
9502   PetscValidType(rhs,2);
9503   PetscValidType(sol,3);
9504   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9505   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9506   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9507   PetscCheckSameComm(F,1,rhs,2);
9508   PetscCheckSameComm(F,1,sol,3);
9509   PetscCall(MatFactorFactorizeSchurComplement(F));
9510   switch (F->schur_status) {
9511   case MAT_FACTOR_SCHUR_FACTORED:
9512     PetscCall(MatSolve(F->schur,rhs,sol));
9513     break;
9514   case MAT_FACTOR_SCHUR_INVERTED:
9515     PetscCall(MatMult(F->schur,rhs,sol));
9516     break;
9517   default:
9518     SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status);
9519   }
9520   PetscFunctionReturn(0);
9521 }
9522 
9523 /*@
9524   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9525 
9526    Logically Collective on Mat
9527 
9528    Input Parameters:
9529 .  F - the factored matrix obtained by calling MatGetFactor()
9530 
9531    Notes:
9532     Must be called after MatFactorSetSchurIS().
9533 
9534    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9535 
9536    Level: advanced
9537 
9538    References:
9539 
9540 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()`
9541 @*/
9542 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9543 {
9544   PetscFunctionBegin;
9545   PetscValidType(F,1);
9546   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9547   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9548   PetscCall(MatFactorFactorizeSchurComplement(F));
9549   PetscCall(MatFactorInvertSchurComplement_Private(F));
9550   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9551   PetscFunctionReturn(0);
9552 }
9553 
9554 /*@
9555   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9556 
9557    Logically Collective on Mat
9558 
9559    Input Parameters:
9560 .  F - the factored matrix obtained by calling MatGetFactor()
9561 
9562    Notes:
9563     Must be called after MatFactorSetSchurIS().
9564 
9565    Level: advanced
9566 
9567    References:
9568 
9569 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()`
9570 @*/
9571 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9572 {
9573   PetscFunctionBegin;
9574   PetscValidType(F,1);
9575   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9576   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9577   PetscCall(MatFactorFactorizeSchurComplement_Private(F));
9578   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9579   PetscFunctionReturn(0);
9580 }
9581 
9582 /*@
9583    MatPtAP - Creates the matrix product C = P^T * A * P
9584 
9585    Neighbor-wise Collective on Mat
9586 
9587    Input Parameters:
9588 +  A - the matrix
9589 .  P - the projection matrix
9590 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9591 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9592           if the result is a dense matrix this is irrelevant
9593 
9594    Output Parameters:
9595 .  C - the product matrix
9596 
9597    Notes:
9598    C will be created and must be destroyed by the user with MatDestroy().
9599 
9600    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9601 
9602    Level: intermediate
9603 
9604 .seealso: `MatMatMult()`, `MatRARt()`
9605 @*/
9606 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9607 {
9608   PetscFunctionBegin;
9609   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9610   PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9611 
9612   if (scall == MAT_INITIAL_MATRIX) {
9613     PetscCall(MatProductCreate(A,P,NULL,C));
9614     PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP));
9615     PetscCall(MatProductSetAlgorithm(*C,"default"));
9616     PetscCall(MatProductSetFill(*C,fill));
9617 
9618     (*C)->product->api_user = PETSC_TRUE;
9619     PetscCall(MatProductSetFromOptions(*C));
9620     PetscCheck((*C)->ops->productsymbolic,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);
9621     PetscCall(MatProductSymbolic(*C));
9622   } else { /* scall == MAT_REUSE_MATRIX */
9623     PetscCall(MatProductReplaceMats(A,P,NULL,*C));
9624   }
9625 
9626   PetscCall(MatProductNumeric(*C));
9627   if (A->symmetric) {
9628     if (A->spd) {
9629       PetscCall(MatSetOption(*C,MAT_SPD,PETSC_TRUE));
9630     } else {
9631       PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE));
9632     }
9633   }
9634   PetscFunctionReturn(0);
9635 }
9636 
9637 /*@
9638    MatRARt - Creates the matrix product C = R * A * R^T
9639 
9640    Neighbor-wise Collective on Mat
9641 
9642    Input Parameters:
9643 +  A - the matrix
9644 .  R - the projection matrix
9645 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9646 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9647           if the result is a dense matrix this is irrelevant
9648 
9649    Output Parameters:
9650 .  C - the product matrix
9651 
9652    Notes:
9653    C will be created and must be destroyed by the user with MatDestroy().
9654 
9655    This routine is currently only implemented for pairs of AIJ matrices and classes
9656    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9657    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9658    We recommend using MatPtAP().
9659 
9660    Level: intermediate
9661 
9662 .seealso: `MatMatMult()`, `MatPtAP()`
9663 @*/
9664 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9665 {
9666   PetscFunctionBegin;
9667   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9668   PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9669 
9670   if (scall == MAT_INITIAL_MATRIX) {
9671     PetscCall(MatProductCreate(A,R,NULL,C));
9672     PetscCall(MatProductSetType(*C,MATPRODUCT_RARt));
9673     PetscCall(MatProductSetAlgorithm(*C,"default"));
9674     PetscCall(MatProductSetFill(*C,fill));
9675 
9676     (*C)->product->api_user = PETSC_TRUE;
9677     PetscCall(MatProductSetFromOptions(*C));
9678     PetscCheck((*C)->ops->productsymbolic,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);
9679     PetscCall(MatProductSymbolic(*C));
9680   } else { /* scall == MAT_REUSE_MATRIX */
9681     PetscCall(MatProductReplaceMats(A,R,NULL,*C));
9682   }
9683 
9684   PetscCall(MatProductNumeric(*C));
9685   if (A->symmetric_set && A->symmetric) {
9686     PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE));
9687   }
9688   PetscFunctionReturn(0);
9689 }
9690 
9691 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9692 {
9693   PetscFunctionBegin;
9694   PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9695 
9696   if (scall == MAT_INITIAL_MATRIX) {
9697     PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]));
9698     PetscCall(MatProductCreate(A,B,NULL,C));
9699     PetscCall(MatProductSetType(*C,ptype));
9700     PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT));
9701     PetscCall(MatProductSetFill(*C,fill));
9702 
9703     (*C)->product->api_user = PETSC_TRUE;
9704     PetscCall(MatProductSetFromOptions(*C));
9705     PetscCall(MatProductSymbolic(*C));
9706   } else { /* scall == MAT_REUSE_MATRIX */
9707     Mat_Product *product = (*C)->product;
9708     PetscBool isdense;
9709 
9710     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,""));
9711     if (isdense && product && product->type != ptype) {
9712       PetscCall(MatProductClear(*C));
9713       product = NULL;
9714     }
9715     PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype]));
9716     if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */
9717       if (isdense) {
9718         PetscCall(MatProductCreate_Private(A,B,NULL,*C));
9719         product = (*C)->product;
9720         product->fill     = fill;
9721         product->api_user = PETSC_TRUE;
9722         product->clear    = PETSC_TRUE;
9723 
9724         PetscCall(MatProductSetType(*C,ptype));
9725         PetscCall(MatProductSetFromOptions(*C));
9726         PetscCheck((*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for %s and %s",MatProductTypes[ptype],((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9727         PetscCall(MatProductSymbolic(*C));
9728       } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first");
9729     } else { /* user may change input matrices A or B when REUSE */
9730       PetscCall(MatProductReplaceMats(A,B,NULL,*C));
9731     }
9732   }
9733   PetscCall(MatProductNumeric(*C));
9734   PetscFunctionReturn(0);
9735 }
9736 
9737 /*@
9738    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9739 
9740    Neighbor-wise Collective on Mat
9741 
9742    Input Parameters:
9743 +  A - the left matrix
9744 .  B - the right matrix
9745 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9746 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9747           if the result is a dense matrix this is irrelevant
9748 
9749    Output Parameters:
9750 .  C - the product matrix
9751 
9752    Notes:
9753    Unless scall is MAT_REUSE_MATRIX C will be created.
9754 
9755    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
9756    call to this function with MAT_INITIAL_MATRIX.
9757 
9758    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9759 
9760    If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly.
9761 
9762    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.
9763 
9764    Example of Usage:
9765 .vb
9766      MatProductCreate(A,B,NULL,&C);
9767      MatProductSetType(C,MATPRODUCT_AB);
9768      MatProductSymbolic(C);
9769      MatProductNumeric(C); // compute C=A * B
9770      MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1
9771      MatProductNumeric(C);
9772      MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1
9773      MatProductNumeric(C);
9774 .ve
9775 
9776    Level: intermediate
9777 
9778 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()`
9779 @*/
9780 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9781 {
9782   PetscFunctionBegin;
9783   PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C));
9784   PetscFunctionReturn(0);
9785 }
9786 
9787 /*@
9788    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9789 
9790    Neighbor-wise Collective on Mat
9791 
9792    Input Parameters:
9793 +  A - the left matrix
9794 .  B - the right matrix
9795 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9796 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9797 
9798    Output Parameters:
9799 .  C - the product matrix
9800 
9801    Notes:
9802    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9803 
9804    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9805 
9806   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9807    actually needed.
9808 
9809    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9810    and for pairs of MPIDense matrices.
9811 
9812    Options Database Keys:
9813 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the
9814               first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9815               the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9816 
9817    Level: intermediate
9818 
9819 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()`
9820 @*/
9821 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9822 {
9823   PetscFunctionBegin;
9824   PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C));
9825   if (A == B) {
9826     PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE));
9827   }
9828   PetscFunctionReturn(0);
9829 }
9830 
9831 /*@
9832    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9833 
9834    Neighbor-wise Collective on Mat
9835 
9836    Input Parameters:
9837 +  A - the left matrix
9838 .  B - the right matrix
9839 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9840 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9841 
9842    Output Parameters:
9843 .  C - the product matrix
9844 
9845    Notes:
9846    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9847 
9848    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9849 
9850   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9851    actually needed.
9852 
9853    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9854    which inherit from SeqAIJ.  C will be of the same type as the input matrices.
9855 
9856    Level: intermediate
9857 
9858 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`
9859 @*/
9860 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9861 {
9862   PetscFunctionBegin;
9863   PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C));
9864   PetscFunctionReturn(0);
9865 }
9866 
9867 /*@
9868    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9869 
9870    Neighbor-wise Collective on Mat
9871 
9872    Input Parameters:
9873 +  A - the left matrix
9874 .  B - the middle matrix
9875 .  C - the right matrix
9876 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9877 -  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
9878           if the result is a dense matrix this is irrelevant
9879 
9880    Output Parameters:
9881 .  D - the product matrix
9882 
9883    Notes:
9884    Unless scall is MAT_REUSE_MATRIX D will be created.
9885 
9886    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9887 
9888    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9889    actually needed.
9890 
9891    If you have many matrices with the same non-zero structure to multiply, you
9892    should use MAT_REUSE_MATRIX in all calls but the first
9893 
9894    Level: intermediate
9895 
9896 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()`
9897 @*/
9898 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9899 {
9900   PetscFunctionBegin;
9901   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6);
9902   PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9903 
9904   if (scall == MAT_INITIAL_MATRIX) {
9905     PetscCall(MatProductCreate(A,B,C,D));
9906     PetscCall(MatProductSetType(*D,MATPRODUCT_ABC));
9907     PetscCall(MatProductSetAlgorithm(*D,"default"));
9908     PetscCall(MatProductSetFill(*D,fill));
9909 
9910     (*D)->product->api_user = PETSC_TRUE;
9911     PetscCall(MatProductSetFromOptions(*D));
9912     PetscCheck((*D)->ops->productsymbolic,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);
9913     PetscCall(MatProductSymbolic(*D));
9914   } else { /* user may change input matrices when REUSE */
9915     PetscCall(MatProductReplaceMats(A,B,C,*D));
9916   }
9917   PetscCall(MatProductNumeric(*D));
9918   PetscFunctionReturn(0);
9919 }
9920 
9921 /*@
9922    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9923 
9924    Collective on Mat
9925 
9926    Input Parameters:
9927 +  mat - the matrix
9928 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9929 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9930 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9931 
9932    Output Parameter:
9933 .  matredundant - redundant matrix
9934 
9935    Notes:
9936    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9937    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9938 
9939    This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before
9940    calling it.
9941 
9942    Level: advanced
9943 
9944 .seealso: `MatDestroy()`
9945 @*/
9946 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9947 {
9948   MPI_Comm       comm;
9949   PetscMPIInt    size;
9950   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9951   Mat_Redundant  *redund=NULL;
9952   PetscSubcomm   psubcomm=NULL;
9953   MPI_Comm       subcomm_in=subcomm;
9954   Mat            *matseq;
9955   IS             isrow,iscol;
9956   PetscBool      newsubcomm=PETSC_FALSE;
9957 
9958   PetscFunctionBegin;
9959   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9960   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9961     PetscValidPointer(*matredundant,5);
9962     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9963   }
9964 
9965   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
9966   if (size == 1 || nsubcomm == 1) {
9967     if (reuse == MAT_INITIAL_MATRIX) {
9968       PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant));
9969     } else {
9970       PetscCheck(*matredundant != mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
9971       PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN));
9972     }
9973     PetscFunctionReturn(0);
9974   }
9975 
9976   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9977   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9978   MatCheckPreallocated(mat,1);
9979 
9980   PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0));
9981   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9982     /* create psubcomm, then get subcomm */
9983     PetscCall(PetscObjectGetComm((PetscObject)mat,&comm));
9984     PetscCallMPI(MPI_Comm_size(comm,&size));
9985     PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size);
9986 
9987     PetscCall(PetscSubcommCreate(comm,&psubcomm));
9988     PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm));
9989     PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS));
9990     PetscCall(PetscSubcommSetFromOptions(psubcomm));
9991     PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL));
9992     newsubcomm = PETSC_TRUE;
9993     PetscCall(PetscSubcommDestroy(&psubcomm));
9994   }
9995 
9996   /* get isrow, iscol and a local sequential matrix matseq[0] */
9997   if (reuse == MAT_INITIAL_MATRIX) {
9998     mloc_sub = PETSC_DECIDE;
9999     nloc_sub = PETSC_DECIDE;
10000     if (bs < 1) {
10001       PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M));
10002       PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N));
10003     } else {
10004       PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M));
10005       PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N));
10006     }
10007     PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm));
10008     rstart = rend - mloc_sub;
10009     PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow));
10010     PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol));
10011   } else { /* reuse == MAT_REUSE_MATRIX */
10012     PetscCheck(*matredundant != mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10013     /* retrieve subcomm */
10014     PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm));
10015     redund = (*matredundant)->redundant;
10016     isrow  = redund->isrow;
10017     iscol  = redund->iscol;
10018     matseq = redund->matseq;
10019   }
10020   PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq));
10021 
10022   /* get matredundant over subcomm */
10023   if (reuse == MAT_INITIAL_MATRIX) {
10024     PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant));
10025 
10026     /* create a supporting struct and attach it to C for reuse */
10027     PetscCall(PetscNewLog(*matredundant,&redund));
10028     (*matredundant)->redundant = redund;
10029     redund->isrow              = isrow;
10030     redund->iscol              = iscol;
10031     redund->matseq             = matseq;
10032     if (newsubcomm) {
10033       redund->subcomm          = subcomm;
10034     } else {
10035       redund->subcomm          = MPI_COMM_NULL;
10036     }
10037   } else {
10038     PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant));
10039   }
10040 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
10041   if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) {
10042     PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE));
10043     PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE));
10044   }
10045 #endif
10046   PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0));
10047   PetscFunctionReturn(0);
10048 }
10049 
10050 /*@C
10051    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10052    a given 'mat' object. Each submatrix can span multiple procs.
10053 
10054    Collective on Mat
10055 
10056    Input Parameters:
10057 +  mat - the matrix
10058 .  subcomm - the subcommunicator obtained by com_split(comm)
10059 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10060 
10061    Output Parameter:
10062 .  subMat - 'parallel submatrices each spans a given subcomm
10063 
10064   Notes:
10065   The submatrix partition across processors is dictated by 'subComm' a
10066   communicator obtained by MPI_comm_split(). The subComm
10067   is not restriced to be grouped with consecutive original ranks.
10068 
10069   Due the MPI_Comm_split() usage, the parallel layout of the submatrices
10070   map directly to the layout of the original matrix [wrt the local
10071   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10072   into the 'DiagonalMat' of the subMat, hence it is used directly from
10073   the subMat. However the offDiagMat looses some columns - and this is
10074   reconstructed with MatSetValues()
10075 
10076   Level: advanced
10077 
10078 .seealso: `MatCreateSubMatrices()`
10079 @*/
10080 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10081 {
10082   PetscMPIInt    commsize,subCommSize;
10083 
10084   PetscFunctionBegin;
10085   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize));
10086   PetscCallMPI(MPI_Comm_size(subComm,&subCommSize));
10087   PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize);
10088 
10089   PetscCheck(scall != MAT_REUSE_MATRIX || *subMat != mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10090   PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0));
10091   PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat));
10092   PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0));
10093   PetscFunctionReturn(0);
10094 }
10095 
10096 /*@
10097    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10098 
10099    Not Collective
10100 
10101    Input Parameters:
10102 +  mat - matrix to extract local submatrix from
10103 .  isrow - local row indices for submatrix
10104 -  iscol - local column indices for submatrix
10105 
10106    Output Parameter:
10107 .  submat - the submatrix
10108 
10109    Level: intermediate
10110 
10111    Notes:
10112    The submat should be returned with MatRestoreLocalSubMatrix().
10113 
10114    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10115    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10116 
10117    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10118    MatSetValuesBlockedLocal() will also be implemented.
10119 
10120    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10121    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10122 
10123 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()`
10124 @*/
10125 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10126 {
10127   PetscFunctionBegin;
10128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10129   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10130   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10131   PetscCheckSameComm(isrow,2,iscol,3);
10132   PetscValidPointer(submat,4);
10133   PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10134 
10135   if (mat->ops->getlocalsubmatrix) {
10136     PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat));
10137   } else {
10138     PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat));
10139   }
10140   PetscFunctionReturn(0);
10141 }
10142 
10143 /*@
10144    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10145 
10146    Not Collective
10147 
10148    Input Parameters:
10149 +  mat - matrix to extract local submatrix from
10150 .  isrow - local row indices for submatrix
10151 .  iscol - local column indices for submatrix
10152 -  submat - the submatrix
10153 
10154    Level: intermediate
10155 
10156 .seealso: `MatGetLocalSubMatrix()`
10157 @*/
10158 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10159 {
10160   PetscFunctionBegin;
10161   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10162   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10163   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10164   PetscCheckSameComm(isrow,2,iscol,3);
10165   PetscValidPointer(submat,4);
10166   if (*submat) {
10167     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10168   }
10169 
10170   if (mat->ops->restorelocalsubmatrix) {
10171     PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat));
10172   } else {
10173     PetscCall(MatDestroy(submat));
10174   }
10175   *submat = NULL;
10176   PetscFunctionReturn(0);
10177 }
10178 
10179 /* --------------------------------------------------------*/
10180 /*@
10181    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10182 
10183    Collective on Mat
10184 
10185    Input Parameter:
10186 .  mat - the matrix
10187 
10188    Output Parameter:
10189 .  is - if any rows have zero diagonals this contains the list of them
10190 
10191    Level: developer
10192 
10193 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()`
10194 @*/
10195 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10196 {
10197   PetscFunctionBegin;
10198   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10199   PetscValidType(mat,1);
10200   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10201   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10202 
10203   if (!mat->ops->findzerodiagonals) {
10204     Vec                diag;
10205     const PetscScalar *a;
10206     PetscInt          *rows;
10207     PetscInt           rStart, rEnd, r, nrow = 0;
10208 
10209     PetscCall(MatCreateVecs(mat, &diag, NULL));
10210     PetscCall(MatGetDiagonal(mat, diag));
10211     PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd));
10212     PetscCall(VecGetArrayRead(diag, &a));
10213     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10214     PetscCall(PetscMalloc1(nrow, &rows));
10215     nrow = 0;
10216     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10217     PetscCall(VecRestoreArrayRead(diag, &a));
10218     PetscCall(VecDestroy(&diag));
10219     PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is));
10220   } else {
10221     PetscCall((*mat->ops->findzerodiagonals)(mat, is));
10222   }
10223   PetscFunctionReturn(0);
10224 }
10225 
10226 /*@
10227    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10228 
10229    Collective on Mat
10230 
10231    Input Parameter:
10232 .  mat - the matrix
10233 
10234    Output Parameter:
10235 .  is - contains the list of rows with off block diagonal entries
10236 
10237    Level: developer
10238 
10239 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()`
10240 @*/
10241 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10242 {
10243   PetscFunctionBegin;
10244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10245   PetscValidType(mat,1);
10246   PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10247   PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10248 
10249   PetscCheck(mat->ops->findoffblockdiagonalentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name);
10250   PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is));
10251   PetscFunctionReturn(0);
10252 }
10253 
10254 /*@C
10255   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10256 
10257   Collective on Mat
10258 
10259   Input Parameters:
10260 . mat - the matrix
10261 
10262   Output Parameters:
10263 . values - the block inverses in column major order (FORTRAN-like)
10264 
10265    Note:
10266      The size of the blocks is determined by the block size of the matrix.
10267 
10268    Fortran Note:
10269      This routine is not available from Fortran.
10270 
10271   Level: advanced
10272 
10273 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()`
10274 @*/
10275 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10276 {
10277   PetscFunctionBegin;
10278   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10279   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10280   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10281   PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10282   PetscCall((*mat->ops->invertblockdiagonal)(mat,values));
10283   PetscFunctionReturn(0);
10284 }
10285 
10286 /*@C
10287   MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries.
10288 
10289   Collective on Mat
10290 
10291   Input Parameters:
10292 + mat - the matrix
10293 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes()
10294 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes()
10295 
10296   Output Parameters:
10297 . values - the block inverses in column major order (FORTRAN-like)
10298 
10299    Note:
10300    This routine is not available from Fortran.
10301 
10302   Level: advanced
10303 
10304 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()`
10305 @*/
10306 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10307 {
10308   PetscFunctionBegin;
10309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10310   PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10311   PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10312   PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10313   PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values));
10314   PetscFunctionReturn(0);
10315 }
10316 
10317 /*@
10318   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10319 
10320   Collective on Mat
10321 
10322   Input Parameters:
10323 . A - the matrix
10324 
10325   Output Parameters:
10326 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10327 
10328   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10329 
10330   Level: advanced
10331 
10332 .seealso: `MatInvertBlockDiagonal()`
10333 @*/
10334 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10335 {
10336   const PetscScalar *vals;
10337   PetscInt          *dnnz;
10338   PetscInt           m,rstart,rend,bs,i,j;
10339 
10340   PetscFunctionBegin;
10341   PetscCall(MatInvertBlockDiagonal(A,&vals));
10342   PetscCall(MatGetBlockSize(A,&bs));
10343   PetscCall(MatGetLocalSize(A,&m,NULL));
10344   PetscCall(MatSetLayouts(C,A->rmap,A->cmap));
10345   PetscCall(PetscMalloc1(m/bs,&dnnz));
10346   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10347   PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL));
10348   PetscCall(PetscFree(dnnz));
10349   PetscCall(MatGetOwnershipRange(C,&rstart,&rend));
10350   PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE));
10351   for (i = rstart/bs; i < rend/bs; i++) {
10352     PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES));
10353   }
10354   PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY));
10355   PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY));
10356   PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE));
10357   PetscFunctionReturn(0);
10358 }
10359 
10360 /*@C
10361     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10362     via MatTransposeColoringCreate().
10363 
10364     Collective on MatTransposeColoring
10365 
10366     Input Parameter:
10367 .   c - coloring context
10368 
10369     Level: intermediate
10370 
10371 .seealso: `MatTransposeColoringCreate()`
10372 @*/
10373 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10374 {
10375   MatTransposeColoring matcolor=*c;
10376 
10377   PetscFunctionBegin;
10378   if (!matcolor) PetscFunctionReturn(0);
10379   if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);}
10380 
10381   PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow));
10382   PetscCall(PetscFree(matcolor->rows));
10383   PetscCall(PetscFree(matcolor->den2sp));
10384   PetscCall(PetscFree(matcolor->colorforcol));
10385   PetscCall(PetscFree(matcolor->columns));
10386   if (matcolor->brows>0) {
10387     PetscCall(PetscFree(matcolor->lstart));
10388   }
10389   PetscCall(PetscHeaderDestroy(c));
10390   PetscFunctionReturn(0);
10391 }
10392 
10393 /*@C
10394     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10395     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10396     MatTransposeColoring to sparse B.
10397 
10398     Collective on MatTransposeColoring
10399 
10400     Input Parameters:
10401 +   B - sparse matrix B
10402 .   Btdense - symbolic dense matrix B^T
10403 -   coloring - coloring context created with MatTransposeColoringCreate()
10404 
10405     Output Parameter:
10406 .   Btdense - dense matrix B^T
10407 
10408     Level: advanced
10409 
10410      Notes:
10411     These are used internally for some implementations of MatRARt()
10412 
10413 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()`
10414 
10415 @*/
10416 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10417 {
10418   PetscFunctionBegin;
10419   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10420   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3);
10421   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10422 
10423   PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10424   PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense));
10425   PetscFunctionReturn(0);
10426 }
10427 
10428 /*@C
10429     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10430     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10431     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10432     Csp from Cden.
10433 
10434     Collective on MatTransposeColoring
10435 
10436     Input Parameters:
10437 +   coloring - coloring context created with MatTransposeColoringCreate()
10438 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10439 
10440     Output Parameter:
10441 .   Csp - sparse matrix
10442 
10443     Level: advanced
10444 
10445      Notes:
10446     These are used internally for some implementations of MatRARt()
10447 
10448 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`
10449 
10450 @*/
10451 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10452 {
10453   PetscFunctionBegin;
10454   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10455   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10456   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10457 
10458   PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10459   PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp));
10460   PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY));
10461   PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY));
10462   PetscFunctionReturn(0);
10463 }
10464 
10465 /*@C
10466    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10467 
10468    Collective on Mat
10469 
10470    Input Parameters:
10471 +  mat - the matrix product C
10472 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10473 
10474     Output Parameter:
10475 .   color - the new coloring context
10476 
10477     Level: intermediate
10478 
10479 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`,
10480           `MatTransColoringApplyDenToSp()`
10481 @*/
10482 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10483 {
10484   MatTransposeColoring c;
10485   MPI_Comm             comm;
10486 
10487   PetscFunctionBegin;
10488   PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0));
10489   PetscCall(PetscObjectGetComm((PetscObject)mat,&comm));
10490   PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL));
10491 
10492   c->ctype = iscoloring->ctype;
10493   if (mat->ops->transposecoloringcreate) {
10494     PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c));
10495   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10496 
10497   *color = c;
10498   PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0));
10499   PetscFunctionReturn(0);
10500 }
10501 
10502 /*@
10503       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10504         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10505         same, otherwise it will be larger
10506 
10507      Not Collective
10508 
10509   Input Parameter:
10510 .    A  - the matrix
10511 
10512   Output Parameter:
10513 .    state - the current state
10514 
10515   Notes:
10516     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10517          different matrices
10518 
10519   Level: intermediate
10520 
10521 @*/
10522 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10523 {
10524   PetscFunctionBegin;
10525   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10526   *state = mat->nonzerostate;
10527   PetscFunctionReturn(0);
10528 }
10529 
10530 /*@
10531       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10532                  matrices from each processor
10533 
10534     Collective
10535 
10536    Input Parameters:
10537 +    comm - the communicators the parallel matrix will live on
10538 .    seqmat - the input sequential matrices
10539 .    n - number of local columns (or PETSC_DECIDE)
10540 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10541 
10542    Output Parameter:
10543 .    mpimat - the parallel matrix generated
10544 
10545     Level: advanced
10546 
10547    Notes:
10548     The number of columns of the matrix in EACH processor MUST be the same.
10549 
10550 @*/
10551 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10552 {
10553   PetscFunctionBegin;
10554   PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10555   PetscCheck(reuse != MAT_REUSE_MATRIX || seqmat != *mpimat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10556 
10557   PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0));
10558   PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat));
10559   PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0));
10560   PetscFunctionReturn(0);
10561 }
10562 
10563 /*@
10564      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10565                  ranks' ownership ranges.
10566 
10567     Collective on A
10568 
10569    Input Parameters:
10570 +    A   - the matrix to create subdomains from
10571 -    N   - requested number of subdomains
10572 
10573    Output Parameters:
10574 +    n   - number of subdomains resulting on this rank
10575 -    iss - IS list with indices of subdomains on this rank
10576 
10577     Level: advanced
10578 
10579     Notes:
10580     number of subdomains must be smaller than the communicator size
10581 @*/
10582 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10583 {
10584   MPI_Comm        comm,subcomm;
10585   PetscMPIInt     size,rank,color;
10586   PetscInt        rstart,rend,k;
10587 
10588   PetscFunctionBegin;
10589   PetscCall(PetscObjectGetComm((PetscObject)A,&comm));
10590   PetscCallMPI(MPI_Comm_size(comm,&size));
10591   PetscCallMPI(MPI_Comm_rank(comm,&rank));
10592   PetscCheck(N >= 1 && N < (PetscInt)size,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %d, got N = %" PetscInt_FMT,size,N);
10593   *n = 1;
10594   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10595   color = rank/k;
10596   PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm));
10597   PetscCall(PetscMalloc1(1,iss));
10598   PetscCall(MatGetOwnershipRange(A,&rstart,&rend));
10599   PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]));
10600   PetscCallMPI(MPI_Comm_free(&subcomm));
10601   PetscFunctionReturn(0);
10602 }
10603 
10604 /*@
10605    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10606 
10607    If the interpolation and restriction operators are the same, uses MatPtAP.
10608    If they are not the same, use MatMatMatMult.
10609 
10610    Once the coarse grid problem is constructed, correct for interpolation operators
10611    that are not of full rank, which can legitimately happen in the case of non-nested
10612    geometric multigrid.
10613 
10614    Input Parameters:
10615 +  restrct - restriction operator
10616 .  dA - fine grid matrix
10617 .  interpolate - interpolation operator
10618 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10619 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10620 
10621    Output Parameters:
10622 .  A - the Galerkin coarse matrix
10623 
10624    Options Database Key:
10625 .  -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used
10626 
10627    Level: developer
10628 
10629 .seealso: `MatPtAP()`, `MatMatMatMult()`
10630 @*/
10631 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10632 {
10633   IS             zerorows;
10634   Vec            diag;
10635 
10636   PetscFunctionBegin;
10637   PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10638   /* Construct the coarse grid matrix */
10639   if (interpolate == restrct) {
10640     PetscCall(MatPtAP(dA,interpolate,reuse,fill,A));
10641   } else {
10642     PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A));
10643   }
10644 
10645   /* If the interpolation matrix is not of full rank, A will have zero rows.
10646      This can legitimately happen in the case of non-nested geometric multigrid.
10647      In that event, we set the rows of the matrix to the rows of the identity,
10648      ignoring the equations (as the RHS will also be zero). */
10649 
10650   PetscCall(MatFindZeroRows(*A, &zerorows));
10651 
10652   if (zerorows != NULL) { /* if there are any zero rows */
10653     PetscCall(MatCreateVecs(*A, &diag, NULL));
10654     PetscCall(MatGetDiagonal(*A, diag));
10655     PetscCall(VecISSet(diag, zerorows, 1.0));
10656     PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES));
10657     PetscCall(VecDestroy(&diag));
10658     PetscCall(ISDestroy(&zerorows));
10659   }
10660   PetscFunctionReturn(0);
10661 }
10662 
10663 /*@C
10664     MatSetOperation - Allows user to set a matrix operation for any matrix type
10665 
10666    Logically Collective on Mat
10667 
10668     Input Parameters:
10669 +   mat - the matrix
10670 .   op - the name of the operation
10671 -   f - the function that provides the operation
10672 
10673    Level: developer
10674 
10675     Usage:
10676 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10677 $      PetscCall(MatCreateXXX(comm,...&A);
10678 $      PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10679 
10680     Notes:
10681     See the file include/petscmat.h for a complete list of matrix
10682     operations, which all have the form MATOP_<OPERATION>, where
10683     <OPERATION> is the name (in all capital letters) of the
10684     user interface routine (e.g., MatMult() -> MATOP_MULT).
10685 
10686     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10687     sequence as the usual matrix interface routines, since they
10688     are intended to be accessed via the usual matrix interface
10689     routines, e.g.,
10690 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10691 
10692     In particular each function MUST return an error code of 0 on success and
10693     nonzero on failure.
10694 
10695     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10696 
10697 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()`
10698 @*/
10699 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10700 {
10701   PetscFunctionBegin;
10702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10703   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10704     mat->ops->viewnative = mat->ops->view;
10705   }
10706   (((void(**)(void))mat->ops)[op]) = f;
10707   PetscFunctionReturn(0);
10708 }
10709 
10710 /*@C
10711     MatGetOperation - Gets a matrix operation for any matrix type.
10712 
10713     Not Collective
10714 
10715     Input Parameters:
10716 +   mat - the matrix
10717 -   op - the name of the operation
10718 
10719     Output Parameter:
10720 .   f - the function that provides the operation
10721 
10722     Level: developer
10723 
10724     Usage:
10725 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10726 $      MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10727 
10728     Notes:
10729     See the file include/petscmat.h for a complete list of matrix
10730     operations, which all have the form MATOP_<OPERATION>, where
10731     <OPERATION> is the name (in all capital letters) of the
10732     user interface routine (e.g., MatMult() -> MATOP_MULT).
10733 
10734     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10735 
10736 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`
10737 @*/
10738 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10739 {
10740   PetscFunctionBegin;
10741   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10742   *f = (((void (**)(void))mat->ops)[op]);
10743   PetscFunctionReturn(0);
10744 }
10745 
10746 /*@
10747     MatHasOperation - Determines whether the given matrix supports the particular
10748     operation.
10749 
10750    Not Collective
10751 
10752    Input Parameters:
10753 +  mat - the matrix
10754 -  op - the operation, for example, MATOP_GET_DIAGONAL
10755 
10756    Output Parameter:
10757 .  has - either PETSC_TRUE or PETSC_FALSE
10758 
10759    Level: advanced
10760 
10761    Notes:
10762    See the file include/petscmat.h for a complete list of matrix
10763    operations, which all have the form MATOP_<OPERATION>, where
10764    <OPERATION> is the name (in all capital letters) of the
10765    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10766 
10767 .seealso: `MatCreateShell()`
10768 @*/
10769 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10770 {
10771   PetscFunctionBegin;
10772   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10773   PetscValidBoolPointer(has,3);
10774   if (mat->ops->hasoperation) {
10775     PetscCall((*mat->ops->hasoperation)(mat,op,has));
10776   } else {
10777     if (((void**)mat->ops)[op]) *has = PETSC_TRUE;
10778     else {
10779       *has = PETSC_FALSE;
10780       if (op == MATOP_CREATE_SUBMATRIX) {
10781         PetscMPIInt size;
10782 
10783         PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
10784         if (size == 1) {
10785           PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has));
10786         }
10787       }
10788     }
10789   }
10790   PetscFunctionReturn(0);
10791 }
10792 
10793 /*@
10794     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10795     of the matrix are congruent
10796 
10797    Collective on mat
10798 
10799    Input Parameters:
10800 .  mat - the matrix
10801 
10802    Output Parameter:
10803 .  cong - either PETSC_TRUE or PETSC_FALSE
10804 
10805    Level: beginner
10806 
10807    Notes:
10808 
10809 .seealso: `MatCreate()`, `MatSetSizes()`
10810 @*/
10811 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10812 {
10813   PetscFunctionBegin;
10814   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10815   PetscValidType(mat,1);
10816   PetscValidBoolPointer(cong,2);
10817   if (!mat->rmap || !mat->cmap) {
10818     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10819     PetscFunctionReturn(0);
10820   }
10821   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10822     PetscCall(PetscLayoutSetUp(mat->rmap));
10823     PetscCall(PetscLayoutSetUp(mat->cmap));
10824     PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong));
10825     if (*cong) mat->congruentlayouts = 1;
10826     else       mat->congruentlayouts = 0;
10827   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10828   PetscFunctionReturn(0);
10829 }
10830 
10831 PetscErrorCode MatSetInf(Mat A)
10832 {
10833   PetscFunctionBegin;
10834   PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type");
10835   PetscCall((*A->ops->setinf)(A));
10836   PetscFunctionReturn(0);
10837 }
10838