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