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