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