xref: /petsc/src/mat/interface/matrix.c (revision 98ed55f01011ad669571857c01fc451e9dc2fe65)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
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_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    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
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64 
65 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
66 @*/
67 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
68 {
69   PetscErrorCode ierr;
70   PetscRandom    randObj = NULL;
71 
72   PetscFunctionBegin;
73   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
74   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
75   PetscValidType(x,1);
76 
77   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
78 
79   if (!rctx) {
80     MPI_Comm comm;
81     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
82     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
83     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
84     rctx = randObj;
85   }
86 
87   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
88   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
89   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90 
91   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
92   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
93   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
94   PetscFunctionReturn(0);
95 }
96 
97 /*@
98    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
99 
100    Logically Collective on Mat
101 
102    Input Parameters:
103 .  mat - the factored matrix
104 
105    Output Parameter:
106 +  pivot - the pivot value computed
107 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
108          the share the matrix
109 
110    Level: advanced
111 
112    Notes:
113     This routine does not work for factorizations done with external packages.
114    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
115 
116    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
117 
118 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
119 @*/
120 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
121 {
122   PetscFunctionBegin;
123   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
124   *pivot = mat->factorerror_zeropivot_value;
125   *row   = mat->factorerror_zeropivot_row;
126   PetscFunctionReturn(0);
127 }
128 
129 /*@
130    MatFactorGetError - gets the error code from a factorization
131 
132    Logically Collective on Mat
133 
134    Input Parameters:
135 .  mat - the factored matrix
136 
137    Output Parameter:
138 .  err  - the error code
139 
140    Level: advanced
141 
142    Notes:
143     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
144 
145 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
146 @*/
147 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
148 {
149   PetscFunctionBegin;
150   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
151   *err = mat->factorerrortype;
152   PetscFunctionReturn(0);
153 }
154 
155 /*@
156    MatFactorClearError - clears the error code in a factorization
157 
158    Logically Collective on Mat
159 
160    Input Parameter:
161 .  mat - the factored matrix
162 
163    Level: developer
164 
165    Notes:
166     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
167 
168 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
169 @*/
170 PetscErrorCode MatFactorClearError(Mat mat)
171 {
172   PetscFunctionBegin;
173   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
174   mat->factorerrortype             = MAT_FACTOR_NOERROR;
175   mat->factorerror_zeropivot_value = 0.0;
176   mat->factorerror_zeropivot_row   = 0;
177   PetscFunctionReturn(0);
178 }
179 
180 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
181 {
182   PetscErrorCode    ierr;
183   Vec               r,l;
184   const PetscScalar *al;
185   PetscInt          i,nz,gnz,N,n;
186 
187   PetscFunctionBegin;
188   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
189   if (!cols) { /* nonzero rows */
190     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
191     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
192     ierr = VecSet(l,0.0);CHKERRQ(ierr);
193     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
194     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
195     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
196   } else { /* nonzero columns */
197     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
198     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
199     ierr = VecSet(r,0.0);CHKERRQ(ierr);
200     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
201     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
202     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
203   }
204   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
205   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
206   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
207   if (gnz != N) {
208     PetscInt *nzr;
209     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
210     if (nz) {
211       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
212       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
213     }
214     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
215   } else *nonzero = NULL;
216   if (!cols) { /* nonzero rows */
217     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
218   } else {
219     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
220   }
221   ierr = VecDestroy(&l);CHKERRQ(ierr);
222   ierr = VecDestroy(&r);CHKERRQ(ierr);
223   PetscFunctionReturn(0);
224 }
225 
226 /*@
227       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
228 
229   Input Parameter:
230 .    A  - the matrix
231 
232   Output Parameter:
233 .    keptrows - the rows that are not completely zero
234 
235   Notes:
236     keptrows is set to NULL if all rows are nonzero.
237 
238   Level: intermediate
239 
240  @*/
241 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
242 {
243   PetscErrorCode ierr;
244 
245   PetscFunctionBegin;
246   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
247   PetscValidType(mat,1);
248   PetscValidPointer(keptrows,2);
249   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
250   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
251   if (!mat->ops->findnonzerorows) {
252     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
253   } else {
254     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
255   }
256   PetscFunctionReturn(0);
257 }
258 
259 /*@
260       MatFindZeroRows - Locate all rows that are completely zero in the matrix
261 
262   Input Parameter:
263 .    A  - the matrix
264 
265   Output Parameter:
266 .    zerorows - the rows that are completely zero
267 
268   Notes:
269     zerorows is set to NULL if no rows are zero.
270 
271   Level: intermediate
272 
273  @*/
274 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
275 {
276   PetscErrorCode ierr;
277   IS keptrows;
278   PetscInt m, n;
279 
280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
281   PetscValidType(mat,1);
282 
283   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
284   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
285      In keeping with this convention, we set zerorows to NULL if there are no zero
286      rows. */
287   if (keptrows == NULL) {
288     *zerorows = NULL;
289   } else {
290     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
291     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
292     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
293   }
294   PetscFunctionReturn(0);
295 }
296 
297 /*@
298    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
299 
300    Not Collective
301 
302    Input Parameters:
303 .   A - the matrix
304 
305    Output Parameters:
306 .   a - the diagonal part (which is a SEQUENTIAL matrix)
307 
308    Notes:
309     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
310           Use caution, as the reference count on the returned matrix is not incremented and it is used as
311 	  part of the containing MPI Mat's normal operation.
312 
313    Level: advanced
314 
315 @*/
316 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
317 {
318   PetscErrorCode ierr;
319 
320   PetscFunctionBegin;
321   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
322   PetscValidType(A,1);
323   PetscValidPointer(a,3);
324   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
325   if (!A->ops->getdiagonalblock) {
326     PetscMPIInt size;
327     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
328     if (size == 1) {
329       *a = A;
330       PetscFunctionReturn(0);
331     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
332   }
333   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
334   PetscFunctionReturn(0);
335 }
336 
337 /*@
338    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
339 
340    Collective on Mat
341 
342    Input Parameters:
343 .  mat - the matrix
344 
345    Output Parameter:
346 .   trace - the sum of the diagonal entries
347 
348    Level: advanced
349 
350 @*/
351 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
352 {
353   PetscErrorCode ierr;
354   Vec            diag;
355 
356   PetscFunctionBegin;
357   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
358   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
359   ierr = VecSum(diag,trace);CHKERRQ(ierr);
360   ierr = VecDestroy(&diag);CHKERRQ(ierr);
361   PetscFunctionReturn(0);
362 }
363 
364 /*@
365    MatRealPart - Zeros out the imaginary part of the matrix
366 
367    Logically Collective on Mat
368 
369    Input Parameters:
370 .  mat - the matrix
371 
372    Level: advanced
373 
374 
375 .seealso: MatImaginaryPart()
376 @*/
377 PetscErrorCode MatRealPart(Mat mat)
378 {
379   PetscErrorCode ierr;
380 
381   PetscFunctionBegin;
382   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
383   PetscValidType(mat,1);
384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
385   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
386   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
387   MatCheckPreallocated(mat,1);
388   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
389 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
390   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
391     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
392   }
393 #endif
394   PetscFunctionReturn(0);
395 }
396 
397 /*@C
398    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
399 
400    Collective on Mat
401 
402    Input Parameter:
403 .  mat - the matrix
404 
405    Output Parameters:
406 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
407 -   ghosts - the global indices of the ghost points
408 
409    Notes:
410     the nghosts and ghosts are suitable to pass into VecCreateGhost()
411 
412    Level: advanced
413 
414 @*/
415 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
416 {
417   PetscErrorCode ierr;
418 
419   PetscFunctionBegin;
420   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
421   PetscValidType(mat,1);
422   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
423   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
424   if (!mat->ops->getghosts) {
425     if (nghosts) *nghosts = 0;
426     if (ghosts) *ghosts = 0;
427   } else {
428     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
429   }
430   PetscFunctionReturn(0);
431 }
432 
433 
434 /*@
435    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
436 
437    Logically Collective on Mat
438 
439    Input Parameters:
440 .  mat - the matrix
441 
442    Level: advanced
443 
444 
445 .seealso: MatRealPart()
446 @*/
447 PetscErrorCode MatImaginaryPart(Mat mat)
448 {
449   PetscErrorCode ierr;
450 
451   PetscFunctionBegin;
452   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
453   PetscValidType(mat,1);
454   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
455   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
456   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
457   MatCheckPreallocated(mat,1);
458   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
459 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
460   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
461     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
462   }
463 #endif
464   PetscFunctionReturn(0);
465 }
466 
467 /*@
468    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
469 
470    Not Collective
471 
472    Input Parameter:
473 .  mat - the matrix
474 
475    Output Parameters:
476 +  missing - is any diagonal missing
477 -  dd - first diagonal entry that is missing (optional) on this process
478 
479    Level: advanced
480 
481 
482 .seealso: MatRealPart()
483 @*/
484 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
485 {
486   PetscErrorCode ierr;
487 
488   PetscFunctionBegin;
489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
490   PetscValidType(mat,1);
491   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
492   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
493   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
494   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
495   PetscFunctionReturn(0);
496 }
497 
498 /*@C
499    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
500    for each row that you get to ensure that your application does
501    not bleed memory.
502 
503    Not Collective
504 
505    Input Parameters:
506 +  mat - the matrix
507 -  row - the row to get
508 
509    Output Parameters:
510 +  ncols -  if not NULL, the number of nonzeros in the row
511 .  cols - if not NULL, the column numbers
512 -  vals - if not NULL, the values
513 
514    Notes:
515    This routine is provided for people who need to have direct access
516    to the structure of a matrix.  We hope that we provide enough
517    high-level matrix routines that few users will need it.
518 
519    MatGetRow() always returns 0-based column indices, regardless of
520    whether the internal representation is 0-based (default) or 1-based.
521 
522    For better efficiency, set cols and/or vals to NULL if you do
523    not wish to extract these quantities.
524 
525    The user can only examine the values extracted with MatGetRow();
526    the values cannot be altered.  To change the matrix entries, one
527    must use MatSetValues().
528 
529    You can only have one call to MatGetRow() outstanding for a particular
530    matrix at a time, per processor. MatGetRow() can only obtain rows
531    associated with the given processor, it cannot get rows from the
532    other processors; for that we suggest using MatCreateSubMatrices(), then
533    MatGetRow() on the submatrix. The row index passed to MatGetRow()
534    is in the global number of rows.
535 
536    Fortran Notes:
537    The calling sequence from Fortran is
538 .vb
539    MatGetRow(matrix,row,ncols,cols,values,ierr)
540          Mat     matrix (input)
541          integer row    (input)
542          integer ncols  (output)
543          integer cols(maxcols) (output)
544          double precision (or double complex) values(maxcols) output
545 .ve
546    where maxcols >= maximum nonzeros in any row of the matrix.
547 
548 
549    Caution:
550    Do not try to change the contents of the output arrays (cols and vals).
551    In some cases, this may corrupt the matrix.
552 
553    Level: advanced
554 
555 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
556 @*/
557 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
558 {
559   PetscErrorCode ierr;
560   PetscInt       incols;
561 
562   PetscFunctionBegin;
563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
564   PetscValidType(mat,1);
565   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
566   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
567   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
568   MatCheckPreallocated(mat,1);
569   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
570   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
571   if (ncols) *ncols = incols;
572   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
573   PetscFunctionReturn(0);
574 }
575 
576 /*@
577    MatConjugate - replaces the matrix values with their complex conjugates
578 
579    Logically Collective on Mat
580 
581    Input Parameters:
582 .  mat - the matrix
583 
584    Level: advanced
585 
586 .seealso:  VecConjugate()
587 @*/
588 PetscErrorCode MatConjugate(Mat mat)
589 {
590 #if defined(PETSC_USE_COMPLEX)
591   PetscErrorCode ierr;
592 
593   PetscFunctionBegin;
594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
595   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
596   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
597   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
598 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
599   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
600     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
601   }
602 #endif
603   PetscFunctionReturn(0);
604 #else
605   return 0;
606 #endif
607 }
608 
609 /*@C
610    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
611 
612    Not Collective
613 
614    Input Parameters:
615 +  mat - the matrix
616 .  row - the row to get
617 .  ncols, cols - the number of nonzeros and their columns
618 -  vals - if nonzero the column values
619 
620    Notes:
621    This routine should be called after you have finished examining the entries.
622 
623    This routine zeros out ncols, cols, and vals. This is to prevent accidental
624    us of the array after it has been restored. If you pass NULL, it will
625    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
626 
627    Fortran Notes:
628    The calling sequence from Fortran is
629 .vb
630    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
631       Mat     matrix (input)
632       integer row    (input)
633       integer ncols  (output)
634       integer cols(maxcols) (output)
635       double precision (or double complex) values(maxcols) output
636 .ve
637    Where maxcols >= maximum nonzeros in any row of the matrix.
638 
639    In Fortran MatRestoreRow() MUST be called after MatGetRow()
640    before another call to MatGetRow() can be made.
641 
642    Level: advanced
643 
644 .seealso:  MatGetRow()
645 @*/
646 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
647 {
648   PetscErrorCode ierr;
649 
650   PetscFunctionBegin;
651   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
652   if (ncols) PetscValidIntPointer(ncols,3);
653   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
654   if (!mat->ops->restorerow) PetscFunctionReturn(0);
655   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
656   if (ncols) *ncols = 0;
657   if (cols)  *cols = NULL;
658   if (vals)  *vals = NULL;
659   PetscFunctionReturn(0);
660 }
661 
662 /*@
663    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
664    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
665 
666    Not Collective
667 
668    Input Parameters:
669 .  mat - the matrix
670 
671    Notes:
672    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
673 
674    Level: advanced
675 
676 .seealso: MatRestoreRowUpperTriangular()
677 @*/
678 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
679 {
680   PetscErrorCode ierr;
681 
682   PetscFunctionBegin;
683   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
684   PetscValidType(mat,1);
685   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
686   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
687   MatCheckPreallocated(mat,1);
688   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
689   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
690   PetscFunctionReturn(0);
691 }
692 
693 /*@
694    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
695 
696    Not Collective
697 
698    Input Parameters:
699 .  mat - the matrix
700 
701    Notes:
702    This routine should be called after you have finished MatGetRow/MatRestoreRow().
703 
704 
705    Level: advanced
706 
707 .seealso:  MatGetRowUpperTriangular()
708 @*/
709 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
710 {
711   PetscErrorCode ierr;
712 
713   PetscFunctionBegin;
714   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
715   PetscValidType(mat,1);
716   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
717   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
718   MatCheckPreallocated(mat,1);
719   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
720   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
721   PetscFunctionReturn(0);
722 }
723 
724 /*@C
725    MatSetOptionsPrefix - Sets the prefix used for searching for all
726    Mat options in the database.
727 
728    Logically Collective on Mat
729 
730    Input Parameter:
731 +  A - the Mat context
732 -  prefix - the prefix to prepend to all option names
733 
734    Notes:
735    A hyphen (-) must NOT be given at the beginning of the prefix name.
736    The first character of all runtime options is AUTOMATICALLY the hyphen.
737 
738    Level: advanced
739 
740 .seealso: MatSetFromOptions()
741 @*/
742 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
743 {
744   PetscErrorCode ierr;
745 
746   PetscFunctionBegin;
747   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
748   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
749   PetscFunctionReturn(0);
750 }
751 
752 /*@C
753    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
754    Mat options in the database.
755 
756    Logically Collective on Mat
757 
758    Input Parameters:
759 +  A - the Mat context
760 -  prefix - the prefix to prepend to all option names
761 
762    Notes:
763    A hyphen (-) must NOT be given at the beginning of the prefix name.
764    The first character of all runtime options is AUTOMATICALLY the hyphen.
765 
766    Level: advanced
767 
768 .seealso: MatGetOptionsPrefix()
769 @*/
770 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
771 {
772   PetscErrorCode ierr;
773 
774   PetscFunctionBegin;
775   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
776   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
777   PetscFunctionReturn(0);
778 }
779 
780 /*@C
781    MatGetOptionsPrefix - Sets the prefix used for searching for all
782    Mat options in the database.
783 
784    Not Collective
785 
786    Input Parameter:
787 .  A - the Mat context
788 
789    Output Parameter:
790 .  prefix - pointer to the prefix string used
791 
792    Notes:
793     On the fortran side, the user should pass in a string 'prefix' of
794    sufficient length to hold the prefix.
795 
796    Level: advanced
797 
798 .seealso: MatAppendOptionsPrefix()
799 @*/
800 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
801 {
802   PetscErrorCode ierr;
803 
804   PetscFunctionBegin;
805   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
806   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
807   PetscFunctionReturn(0);
808 }
809 
810 /*@
811    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
812 
813    Collective on Mat
814 
815    Input Parameters:
816 .  A - the Mat context
817 
818    Notes:
819    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
820    Currently support MPIAIJ and SEQAIJ.
821 
822    Level: beginner
823 
824 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
825 @*/
826 PetscErrorCode MatResetPreallocation(Mat A)
827 {
828   PetscErrorCode ierr;
829 
830   PetscFunctionBegin;
831   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
832   PetscValidType(A,1);
833   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
834   PetscFunctionReturn(0);
835 }
836 
837 
838 /*@
839    MatSetUp - Sets up the internal matrix data structures for the later use.
840 
841    Collective on Mat
842 
843    Input Parameters:
844 .  A - the Mat context
845 
846    Notes:
847    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
848 
849    If a suitable preallocation routine is used, this function does not need to be called.
850 
851    See the Performance chapter of the PETSc users manual for how to preallocate matrices
852 
853    Level: beginner
854 
855 .seealso: MatCreate(), MatDestroy()
856 @*/
857 PetscErrorCode MatSetUp(Mat A)
858 {
859   PetscMPIInt    size;
860   PetscErrorCode ierr;
861 
862   PetscFunctionBegin;
863   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
864   if (!((PetscObject)A)->type_name) {
865     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
866     if (size == 1) {
867       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
868     } else {
869       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
870     }
871   }
872   if (!A->preallocated && A->ops->setup) {
873     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
874     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
875   }
876   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
877   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
878   A->preallocated = PETSC_TRUE;
879   PetscFunctionReturn(0);
880 }
881 
882 #if defined(PETSC_HAVE_SAWS)
883 #include <petscviewersaws.h>
884 #endif
885 /*@C
886    MatView - Visualizes a matrix object.
887 
888    Collective on Mat
889 
890    Input Parameters:
891 +  mat - the matrix
892 -  viewer - visualization context
893 
894   Notes:
895   The available visualization contexts include
896 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
897 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
898 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
899 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
900 
901    The user can open alternative visualization contexts with
902 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
903 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
904          specified file; corresponding input uses MatLoad()
905 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
906          an X window display
907 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
908          Currently only the sequential dense and AIJ
909          matrix types support the Socket viewer.
910 
911    The user can call PetscViewerPushFormat() to specify the output
912    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
913    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
914 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
915 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
916 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
917 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
918          format common among all matrix types
919 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
920          format (which is in many cases the same as the default)
921 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
922          size and structure (not the matrix entries)
923 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
924          the matrix structure
925 
926    Options Database Keys:
927 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
928 .  -mat_view ::ascii_info_detail - Prints more detailed info
929 .  -mat_view - Prints matrix in ASCII format
930 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
931 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
932 .  -display <name> - Sets display name (default is host)
933 .  -draw_pause <sec> - Sets number of seconds to pause after display
934 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
935 .  -viewer_socket_machine <machine> -
936 .  -viewer_socket_port <port> -
937 .  -mat_view binary - save matrix to file in binary format
938 -  -viewer_binary_filename <name> -
939    Level: beginner
940 
941    Notes:
942     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
943     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
944 
945     See the manual page for MatLoad() for the exact format of the binary file when the binary
946       viewer is used.
947 
948       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
949       viewer is used.
950 
951       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
952       and then use the following mouse functions.
953 + left mouse: zoom in
954 . middle mouse: zoom out
955 - right mouse: continue with the simulation
956 
957 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
958           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
959 @*/
960 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
961 {
962   PetscErrorCode    ierr;
963   PetscInt          rows,cols,rbs,cbs;
964   PetscBool         iascii,ibinary,isstring;
965   PetscViewerFormat format;
966   PetscMPIInt       size;
967 #if defined(PETSC_HAVE_SAWS)
968   PetscBool         issaws;
969 #endif
970 
971   PetscFunctionBegin;
972   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
973   PetscValidType(mat,1);
974   if (!viewer) {
975     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
976   }
977   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
978   PetscCheckSameComm(mat,1,viewer,2);
979   MatCheckPreallocated(mat,1);
980   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
981   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
982   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
983   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
984   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
985   if (ibinary) {
986     PetscBool mpiio;
987     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
988     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
989   }
990 
991   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
992   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
993   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
994     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
995   }
996 
997 #if defined(PETSC_HAVE_SAWS)
998   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
999 #endif
1000   if (iascii) {
1001     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1002     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1003     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1004       MatNullSpace nullsp,transnullsp;
1005 
1006       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1007       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1008       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1009       if (rbs != 1 || cbs != 1) {
1010         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1011         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1012       } else {
1013         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1014       }
1015       if (mat->factortype) {
1016         MatSolverType solver;
1017         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1018         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1019       }
1020       if (mat->ops->getinfo) {
1021         MatInfo info;
1022         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1023         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1024         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1025       }
1026       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1027       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1028       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1029       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1030       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1031       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1032     }
1033 #if defined(PETSC_HAVE_SAWS)
1034   } else if (issaws) {
1035     PetscMPIInt rank;
1036 
1037     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1038     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1039     if (!((PetscObject)mat)->amsmem && !rank) {
1040       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1041     }
1042 #endif
1043   } else if (isstring) {
1044     const char *type;
1045     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1046     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1047     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1048   }
1049   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1050     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1051     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1052     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1053   } else if (mat->ops->view) {
1054     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1055     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1056     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1057   }
1058   if (iascii) {
1059     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1060     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1061       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1062     }
1063   }
1064   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1065   PetscFunctionReturn(0);
1066 }
1067 
1068 #if defined(PETSC_USE_DEBUG)
1069 #include <../src/sys/totalview/tv_data_display.h>
1070 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1071 {
1072   TV_add_row("Local rows", "int", &mat->rmap->n);
1073   TV_add_row("Local columns", "int", &mat->cmap->n);
1074   TV_add_row("Global rows", "int", &mat->rmap->N);
1075   TV_add_row("Global columns", "int", &mat->cmap->N);
1076   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1077   return TV_format_OK;
1078 }
1079 #endif
1080 
1081 /*@C
1082    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1083    with MatView().  The matrix format is determined from the options database.
1084    Generates a parallel MPI matrix if the communicator has more than one
1085    processor.  The default matrix type is AIJ.
1086 
1087    Collective on PetscViewer
1088 
1089    Input Parameters:
1090 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1091             or some related function before a call to MatLoad()
1092 -  viewer - binary/HDF5 file viewer
1093 
1094    Options Database Keys:
1095    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1096    block size
1097 .    -matload_block_size <bs>
1098 
1099    Level: beginner
1100 
1101    Notes:
1102    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1103    Mat before calling this routine if you wish to set it from the options database.
1104 
1105    MatLoad() automatically loads into the options database any options
1106    given in the file filename.info where filename is the name of the file
1107    that was passed to the PetscViewerBinaryOpen(). The options in the info
1108    file will be ignored if you use the -viewer_binary_skip_info option.
1109 
1110    If the type or size of newmat is not set before a call to MatLoad, PETSc
1111    sets the default matrix type AIJ and sets the local and global sizes.
1112    If type and/or size is already set, then the same are used.
1113 
1114    In parallel, each processor can load a subset of rows (or the
1115    entire matrix).  This routine is especially useful when a large
1116    matrix is stored on disk and only part of it is desired on each
1117    processor.  For example, a parallel solver may access only some of
1118    the rows from each processor.  The algorithm used here reads
1119    relatively small blocks of data rather than reading the entire
1120    matrix and then subsetting it.
1121 
1122    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1123    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1124    or the sequence like
1125 $    PetscViewer v;
1126 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1127 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1128 $    PetscViewerSetFromOptions(v);
1129 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1130 $    PetscViewerFileSetName(v,"datafile");
1131    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1132 $ -viewer_type {binary,hdf5}
1133 
1134    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1135    and src/mat/examples/tutorials/ex10.c with the second approach.
1136 
1137    Notes about the PETSc binary format:
1138    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1139    is read onto rank 0 and then shipped to its destination rank, one after another.
1140    Multiple objects, both matrices and vectors, can be stored within the same file.
1141    Their PetscObject name is ignored; they are loaded in the order of their storage.
1142 
1143    Most users should not need to know the details of the binary storage
1144    format, since MatLoad() and MatView() completely hide these details.
1145    But for anyone who's interested, the standard binary matrix storage
1146    format is
1147 
1148 $    int    MAT_FILE_CLASSID
1149 $    int    number of rows
1150 $    int    number of columns
1151 $    int    total number of nonzeros
1152 $    int    *number nonzeros in each row
1153 $    int    *column indices of all nonzeros (starting index is zero)
1154 $    PetscScalar *values of all nonzeros
1155 
1156    PETSc automatically does the byte swapping for
1157 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1158 linux, Windows and the paragon; thus if you write your own binary
1159 read/write routines you have to swap the bytes; see PetscBinaryRead()
1160 and PetscBinaryWrite() to see how this may be done.
1161 
1162    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1163    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1164    Each processor's chunk is loaded independently by its owning rank.
1165    Multiple objects, both matrices and vectors, can be stored within the same file.
1166    They are looked up by their PetscObject name.
1167 
1168    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1169    by default the same structure and naming of the AIJ arrays and column count
1170    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1171 $    save example.mat A b -v7.3
1172    can be directly read by this routine (see Reference 1 for details).
1173    Note that depending on your MATLAB version, this format might be a default,
1174    otherwise you can set it as default in Preferences.
1175 
1176    Unless -nocompression flag is used to save the file in MATLAB,
1177    PETSc must be configured with ZLIB package.
1178 
1179    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1180 
1181    Current HDF5 (MAT-File) limitations:
1182    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1183 
1184    Corresponding MatView() is not yet implemented.
1185 
1186    The loaded matrix is actually a transpose of the original one in MATLAB,
1187    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1188    With this format, matrix is automatically transposed by PETSc,
1189    unless the matrix is marked as SPD or symmetric
1190    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1191 
1192    References:
1193 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1194 
1195 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1196 
1197  @*/
1198 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1199 {
1200   PetscErrorCode ierr;
1201   PetscBool      flg;
1202 
1203   PetscFunctionBegin;
1204   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1205   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1206 
1207   if (!((PetscObject)newmat)->type_name) {
1208     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1209   }
1210 
1211   flg  = PETSC_FALSE;
1212   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1213   if (flg) {
1214     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1215     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1216   }
1217   flg  = PETSC_FALSE;
1218   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1219   if (flg) {
1220     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1221   }
1222 
1223   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1224   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1225   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1226   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1227   PetscFunctionReturn(0);
1228 }
1229 
1230 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1231 {
1232   PetscErrorCode ierr;
1233   Mat_Redundant  *redund = *redundant;
1234   PetscInt       i;
1235 
1236   PetscFunctionBegin;
1237   if (redund){
1238     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1239       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1240       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1241       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1242     } else {
1243       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1244       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1245       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1246       for (i=0; i<redund->nrecvs; i++) {
1247         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1248         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1249       }
1250       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1251     }
1252 
1253     if (redund->subcomm) {
1254       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1255     }
1256     ierr = PetscFree(redund);CHKERRQ(ierr);
1257   }
1258   PetscFunctionReturn(0);
1259 }
1260 
1261 /*@
1262    MatDestroy - Frees space taken by a matrix.
1263 
1264    Collective on Mat
1265 
1266    Input Parameter:
1267 .  A - the matrix
1268 
1269    Level: beginner
1270 
1271 @*/
1272 PetscErrorCode MatDestroy(Mat *A)
1273 {
1274   PetscErrorCode ierr;
1275 
1276   PetscFunctionBegin;
1277   if (!*A) PetscFunctionReturn(0);
1278   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1279   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1280 
1281   /* if memory was published with SAWs then destroy it */
1282   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1283   if ((*A)->ops->destroy) {
1284     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1285   }
1286 
1287   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1288   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1289   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1290   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1291   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1292   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1293   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1294   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1295   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1296   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1297   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1298   PetscFunctionReturn(0);
1299 }
1300 
1301 /*@C
1302    MatSetValues - Inserts or adds a block of values into a matrix.
1303    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1304    MUST be called after all calls to MatSetValues() have been completed.
1305 
1306    Not Collective
1307 
1308    Input Parameters:
1309 +  mat - the matrix
1310 .  v - a logically two-dimensional array of values
1311 .  m, idxm - the number of rows and their global indices
1312 .  n, idxn - the number of columns and their global indices
1313 -  addv - either ADD_VALUES or INSERT_VALUES, where
1314    ADD_VALUES adds values to any existing entries, and
1315    INSERT_VALUES replaces existing entries with new values
1316 
1317    Notes:
1318    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1319       MatSetUp() before using this routine
1320 
1321    By default the values, v, are row-oriented. See MatSetOption() for other options.
1322 
1323    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1324    options cannot be mixed without intervening calls to the assembly
1325    routines.
1326 
1327    MatSetValues() uses 0-based row and column numbers in Fortran
1328    as well as in C.
1329 
1330    Negative indices may be passed in idxm and idxn, these rows and columns are
1331    simply ignored. This allows easily inserting element stiffness matrices
1332    with homogeneous Dirchlet boundary conditions that you don't want represented
1333    in the matrix.
1334 
1335    Efficiency Alert:
1336    The routine MatSetValuesBlocked() may offer much better efficiency
1337    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1338 
1339    Level: beginner
1340 
1341    Developer Notes:
1342     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1343                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1344 
1345 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1346           InsertMode, INSERT_VALUES, ADD_VALUES
1347 @*/
1348 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1349 {
1350   PetscErrorCode ierr;
1351 #if defined(PETSC_USE_DEBUG)
1352   PetscInt       i,j;
1353 #endif
1354 
1355   PetscFunctionBeginHot;
1356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1357   PetscValidType(mat,1);
1358   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1359   PetscValidIntPointer(idxm,3);
1360   PetscValidIntPointer(idxn,5);
1361   MatCheckPreallocated(mat,1);
1362 
1363   if (mat->insertmode == NOT_SET_VALUES) {
1364     mat->insertmode = addv;
1365   }
1366 #if defined(PETSC_USE_DEBUG)
1367   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1368   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1369   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1370 
1371   for (i=0; i<m; i++) {
1372     for (j=0; j<n; j++) {
1373       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1374 #if defined(PETSC_USE_COMPLEX)
1375         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1376 #else
1377         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1378 #endif
1379     }
1380   }
1381 #endif
1382 
1383   if (mat->assembled) {
1384     mat->was_assembled = PETSC_TRUE;
1385     mat->assembled     = PETSC_FALSE;
1386   }
1387   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1388   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1389   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1391   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1392     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1393   }
1394 #endif
1395   PetscFunctionReturn(0);
1396 }
1397 
1398 
1399 /*@
1400    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1401         values into a matrix
1402 
1403    Not Collective
1404 
1405    Input Parameters:
1406 +  mat - the matrix
1407 .  row - the (block) row to set
1408 -  v - a logically two-dimensional array of values
1409 
1410    Notes:
1411    By the values, v, are column-oriented (for the block version) and sorted
1412 
1413    All the nonzeros in the row must be provided
1414 
1415    The matrix must have previously had its column indices set
1416 
1417    The row must belong to this process
1418 
1419    Level: intermediate
1420 
1421 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1422           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1423 @*/
1424 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1425 {
1426   PetscErrorCode ierr;
1427   PetscInt       globalrow;
1428 
1429   PetscFunctionBegin;
1430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1431   PetscValidType(mat,1);
1432   PetscValidScalarPointer(v,2);
1433   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1434   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1435 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1436   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1437     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1438   }
1439 #endif
1440   PetscFunctionReturn(0);
1441 }
1442 
1443 /*@
1444    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1445         values into a matrix
1446 
1447    Not Collective
1448 
1449    Input Parameters:
1450 +  mat - the matrix
1451 .  row - the (block) row to set
1452 -  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
1453 
1454    Notes:
1455    The values, v, are column-oriented for the block version.
1456 
1457    All the nonzeros in the row must be provided
1458 
1459    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1460 
1461    The row must belong to this process
1462 
1463    Level: advanced
1464 
1465 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1466           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1467 @*/
1468 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1469 {
1470   PetscErrorCode ierr;
1471 
1472   PetscFunctionBeginHot;
1473   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1474   PetscValidType(mat,1);
1475   MatCheckPreallocated(mat,1);
1476   PetscValidScalarPointer(v,2);
1477 #if defined(PETSC_USE_DEBUG)
1478   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1479   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1480 #endif
1481   mat->insertmode = INSERT_VALUES;
1482 
1483   if (mat->assembled) {
1484     mat->was_assembled = PETSC_TRUE;
1485     mat->assembled     = PETSC_FALSE;
1486   }
1487   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1488   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1489   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1490   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1491 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1492   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1493     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1494   }
1495 #endif
1496   PetscFunctionReturn(0);
1497 }
1498 
1499 /*@
1500    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1501      Using structured grid indexing
1502 
1503    Not Collective
1504 
1505    Input Parameters:
1506 +  mat - the matrix
1507 .  m - number of rows being entered
1508 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1509 .  n - number of columns being entered
1510 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1511 .  v - a logically two-dimensional array of values
1512 -  addv - either ADD_VALUES or INSERT_VALUES, where
1513    ADD_VALUES adds values to any existing entries, and
1514    INSERT_VALUES replaces existing entries with new values
1515 
1516    Notes:
1517    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1518 
1519    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1520    options cannot be mixed without intervening calls to the assembly
1521    routines.
1522 
1523    The grid coordinates are across the entire grid, not just the local portion
1524 
1525    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1526    as well as in C.
1527 
1528    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1529 
1530    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1531    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1532 
1533    The columns and rows in the stencil passed in MUST be contained within the
1534    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1535    if you create a DMDA with an overlap of one grid level and on a particular process its first
1536    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1537    first i index you can use in your column and row indices in MatSetStencil() is 5.
1538 
1539    In Fortran idxm and idxn should be declared as
1540 $     MatStencil idxm(4,m),idxn(4,n)
1541    and the values inserted using
1542 $    idxm(MatStencil_i,1) = i
1543 $    idxm(MatStencil_j,1) = j
1544 $    idxm(MatStencil_k,1) = k
1545 $    idxm(MatStencil_c,1) = c
1546    etc
1547 
1548    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1549    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1550    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1551    DM_BOUNDARY_PERIODIC boundary type.
1552 
1553    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
1554    a single value per point) you can skip filling those indices.
1555 
1556    Inspired by the structured grid interface to the HYPRE package
1557    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1558 
1559    Efficiency Alert:
1560    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1561    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1562 
1563    Level: beginner
1564 
1565 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1566           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1567 @*/
1568 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1569 {
1570   PetscErrorCode ierr;
1571   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1572   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1573   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1574 
1575   PetscFunctionBegin;
1576   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1578   PetscValidType(mat,1);
1579   PetscValidIntPointer(idxm,3);
1580   PetscValidIntPointer(idxn,5);
1581 
1582   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1583     jdxm = buf; jdxn = buf+m;
1584   } else {
1585     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1586     jdxm = bufm; jdxn = bufn;
1587   }
1588   for (i=0; i<m; i++) {
1589     for (j=0; j<3-sdim; j++) dxm++;
1590     tmp = *dxm++ - starts[0];
1591     for (j=0; j<dim-1; j++) {
1592       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1593       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1594     }
1595     if (mat->stencil.noc) dxm++;
1596     jdxm[i] = tmp;
1597   }
1598   for (i=0; i<n; i++) {
1599     for (j=0; j<3-sdim; j++) dxn++;
1600     tmp = *dxn++ - starts[0];
1601     for (j=0; j<dim-1; j++) {
1602       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1603       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1604     }
1605     if (mat->stencil.noc) dxn++;
1606     jdxn[i] = tmp;
1607   }
1608   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1609   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1610   PetscFunctionReturn(0);
1611 }
1612 
1613 /*@
1614    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1615      Using structured grid indexing
1616 
1617    Not Collective
1618 
1619    Input Parameters:
1620 +  mat - the matrix
1621 .  m - number of rows being entered
1622 .  idxm - grid coordinates for matrix rows being entered
1623 .  n - number of columns being entered
1624 .  idxn - grid coordinates for matrix columns being entered
1625 .  v - a logically two-dimensional array of values
1626 -  addv - either ADD_VALUES or INSERT_VALUES, where
1627    ADD_VALUES adds values to any existing entries, and
1628    INSERT_VALUES replaces existing entries with new values
1629 
1630    Notes:
1631    By default the values, v, are row-oriented and unsorted.
1632    See MatSetOption() for other options.
1633 
1634    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1635    options cannot be mixed without intervening calls to the assembly
1636    routines.
1637 
1638    The grid coordinates are across the entire grid, not just the local portion
1639 
1640    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1641    as well as in C.
1642 
1643    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1644 
1645    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1646    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1647 
1648    The columns and rows in the stencil passed in MUST be contained within the
1649    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1650    if you create a DMDA with an overlap of one grid level and on a particular process its first
1651    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1652    first i index you can use in your column and row indices in MatSetStencil() is 5.
1653 
1654    In Fortran idxm and idxn should be declared as
1655 $     MatStencil idxm(4,m),idxn(4,n)
1656    and the values inserted using
1657 $    idxm(MatStencil_i,1) = i
1658 $    idxm(MatStencil_j,1) = j
1659 $    idxm(MatStencil_k,1) = k
1660    etc
1661 
1662    Negative indices may be passed in idxm and idxn, these rows and columns are
1663    simply ignored. This allows easily inserting element stiffness matrices
1664    with homogeneous Dirchlet boundary conditions that you don't want represented
1665    in the matrix.
1666 
1667    Inspired by the structured grid interface to the HYPRE package
1668    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1669 
1670    Level: beginner
1671 
1672 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1673           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1674           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1675 @*/
1676 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1677 {
1678   PetscErrorCode ierr;
1679   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1680   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1681   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1682 
1683   PetscFunctionBegin;
1684   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1685   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1686   PetscValidType(mat,1);
1687   PetscValidIntPointer(idxm,3);
1688   PetscValidIntPointer(idxn,5);
1689   PetscValidScalarPointer(v,6);
1690 
1691   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1692     jdxm = buf; jdxn = buf+m;
1693   } else {
1694     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1695     jdxm = bufm; jdxn = bufn;
1696   }
1697   for (i=0; i<m; i++) {
1698     for (j=0; j<3-sdim; j++) dxm++;
1699     tmp = *dxm++ - starts[0];
1700     for (j=0; j<sdim-1; j++) {
1701       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1702       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1703     }
1704     dxm++;
1705     jdxm[i] = tmp;
1706   }
1707   for (i=0; i<n; i++) {
1708     for (j=0; j<3-sdim; j++) dxn++;
1709     tmp = *dxn++ - starts[0];
1710     for (j=0; j<sdim-1; j++) {
1711       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1712       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1713     }
1714     dxn++;
1715     jdxn[i] = tmp;
1716   }
1717   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1718   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1719 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1720   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1721     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1722   }
1723 #endif
1724   PetscFunctionReturn(0);
1725 }
1726 
1727 /*@
1728    MatSetStencil - Sets the grid information for setting values into a matrix via
1729         MatSetValuesStencil()
1730 
1731    Not Collective
1732 
1733    Input Parameters:
1734 +  mat - the matrix
1735 .  dim - dimension of the grid 1, 2, or 3
1736 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1737 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1738 -  dof - number of degrees of freedom per node
1739 
1740 
1741    Inspired by the structured grid interface to the HYPRE package
1742    (www.llnl.gov/CASC/hyper)
1743 
1744    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1745    user.
1746 
1747    Level: beginner
1748 
1749 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1750           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1751 @*/
1752 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1753 {
1754   PetscInt i;
1755 
1756   PetscFunctionBegin;
1757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1758   PetscValidIntPointer(dims,3);
1759   PetscValidIntPointer(starts,4);
1760 
1761   mat->stencil.dim = dim + (dof > 1);
1762   for (i=0; i<dim; i++) {
1763     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1764     mat->stencil.starts[i] = starts[dim-i-1];
1765   }
1766   mat->stencil.dims[dim]   = dof;
1767   mat->stencil.starts[dim] = 0;
1768   mat->stencil.noc         = (PetscBool)(dof == 1);
1769   PetscFunctionReturn(0);
1770 }
1771 
1772 /*@C
1773    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1774 
1775    Not Collective
1776 
1777    Input Parameters:
1778 +  mat - the matrix
1779 .  v - a logically two-dimensional array of values
1780 .  m, idxm - the number of block rows and their global block indices
1781 .  n, idxn - the number of block columns and their global block indices
1782 -  addv - either ADD_VALUES or INSERT_VALUES, where
1783    ADD_VALUES adds values to any existing entries, and
1784    INSERT_VALUES replaces existing entries with new values
1785 
1786    Notes:
1787    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1788    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1789 
1790    The m and n count the NUMBER of blocks in the row direction and column direction,
1791    NOT the total number of rows/columns; for example, if the block size is 2 and
1792    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1793    The values in idxm would be 1 2; that is the first index for each block divided by
1794    the block size.
1795 
1796    Note that you must call MatSetBlockSize() when constructing this matrix (before
1797    preallocating it).
1798 
1799    By default the values, v, are row-oriented, so the layout of
1800    v is the same as for MatSetValues(). See MatSetOption() for other options.
1801 
1802    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1803    options cannot be mixed without intervening calls to the assembly
1804    routines.
1805 
1806    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1807    as well as in C.
1808 
1809    Negative indices may be passed in idxm and idxn, these rows and columns are
1810    simply ignored. This allows easily inserting element stiffness matrices
1811    with homogeneous Dirchlet boundary conditions that you don't want represented
1812    in the matrix.
1813 
1814    Each time an entry is set within a sparse matrix via MatSetValues(),
1815    internal searching must be done to determine where to place the
1816    data in the matrix storage space.  By instead inserting blocks of
1817    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1818    reduced.
1819 
1820    Example:
1821 $   Suppose m=n=2 and block size(bs) = 2 The array is
1822 $
1823 $   1  2  | 3  4
1824 $   5  6  | 7  8
1825 $   - - - | - - -
1826 $   9  10 | 11 12
1827 $   13 14 | 15 16
1828 $
1829 $   v[] should be passed in like
1830 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1831 $
1832 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1833 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1834 
1835    Level: intermediate
1836 
1837 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1838 @*/
1839 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1840 {
1841   PetscErrorCode ierr;
1842 
1843   PetscFunctionBeginHot;
1844   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1845   PetscValidType(mat,1);
1846   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1847   PetscValidIntPointer(idxm,3);
1848   PetscValidIntPointer(idxn,5);
1849   PetscValidScalarPointer(v,6);
1850   MatCheckPreallocated(mat,1);
1851   if (mat->insertmode == NOT_SET_VALUES) {
1852     mat->insertmode = addv;
1853   }
1854 #if defined(PETSC_USE_DEBUG)
1855   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1856   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1857   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1858 #endif
1859 
1860   if (mat->assembled) {
1861     mat->was_assembled = PETSC_TRUE;
1862     mat->assembled     = PETSC_FALSE;
1863   }
1864   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1865   if (mat->ops->setvaluesblocked) {
1866     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1867   } else {
1868     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1869     PetscInt i,j,bs,cbs;
1870     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1871     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1872       iidxm = buf; iidxn = buf + m*bs;
1873     } else {
1874       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1875       iidxm = bufr; iidxn = bufc;
1876     }
1877     for (i=0; i<m; i++) {
1878       for (j=0; j<bs; j++) {
1879         iidxm[i*bs+j] = bs*idxm[i] + j;
1880       }
1881     }
1882     for (i=0; i<n; i++) {
1883       for (j=0; j<cbs; j++) {
1884         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1885       }
1886     }
1887     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1888     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1889   }
1890   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1891 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1892   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1893     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1894   }
1895 #endif
1896   PetscFunctionReturn(0);
1897 }
1898 
1899 /*@
1900    MatGetValues - Gets a block of values from a matrix.
1901 
1902    Not Collective; currently only returns a local block
1903 
1904    Input Parameters:
1905 +  mat - the matrix
1906 .  v - a logically two-dimensional array for storing the values
1907 .  m, idxm - the number of rows and their global indices
1908 -  n, idxn - the number of columns and their global indices
1909 
1910    Notes:
1911    The user must allocate space (m*n PetscScalars) for the values, v.
1912    The values, v, are then returned in a row-oriented format,
1913    analogous to that used by default in MatSetValues().
1914 
1915    MatGetValues() uses 0-based row and column numbers in
1916    Fortran as well as in C.
1917 
1918    MatGetValues() requires that the matrix has been assembled
1919    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1920    MatSetValues() and MatGetValues() CANNOT be made in succession
1921    without intermediate matrix assembly.
1922 
1923    Negative row or column indices will be ignored and those locations in v[] will be
1924    left unchanged.
1925 
1926    Level: advanced
1927 
1928 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1929 @*/
1930 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1931 {
1932   PetscErrorCode ierr;
1933 
1934   PetscFunctionBegin;
1935   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1936   PetscValidType(mat,1);
1937   if (!m || !n) PetscFunctionReturn(0);
1938   PetscValidIntPointer(idxm,3);
1939   PetscValidIntPointer(idxn,5);
1940   PetscValidScalarPointer(v,6);
1941   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1942   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1943   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1944   MatCheckPreallocated(mat,1);
1945 
1946   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1947   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1948   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1949   PetscFunctionReturn(0);
1950 }
1951 
1952 /*@
1953   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1954   the same size. Currently, this can only be called once and creates the given matrix.
1955 
1956   Not Collective
1957 
1958   Input Parameters:
1959 + mat - the matrix
1960 . nb - the number of blocks
1961 . bs - the number of rows (and columns) in each block
1962 . rows - a concatenation of the rows for each block
1963 - v - a concatenation of logically two-dimensional arrays of values
1964 
1965   Notes:
1966   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1967 
1968   Level: advanced
1969 
1970 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1971           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1972 @*/
1973 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1974 {
1975   PetscErrorCode ierr;
1976 
1977   PetscFunctionBegin;
1978   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1979   PetscValidType(mat,1);
1980   PetscValidScalarPointer(rows,4);
1981   PetscValidScalarPointer(v,5);
1982 #if defined(PETSC_USE_DEBUG)
1983   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1984 #endif
1985 
1986   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1987   if (mat->ops->setvaluesbatch) {
1988     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1989   } else {
1990     PetscInt b;
1991     for (b = 0; b < nb; ++b) {
1992       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1993     }
1994   }
1995   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1996   PetscFunctionReturn(0);
1997 }
1998 
1999 /*@
2000    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2001    the routine MatSetValuesLocal() to allow users to insert matrix entries
2002    using a local (per-processor) numbering.
2003 
2004    Not Collective
2005 
2006    Input Parameters:
2007 +  x - the matrix
2008 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2009 - cmapping - column mapping
2010 
2011    Level: intermediate
2012 
2013 
2014 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2015 @*/
2016 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2017 {
2018   PetscErrorCode ierr;
2019 
2020   PetscFunctionBegin;
2021   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2022   PetscValidType(x,1);
2023   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2024   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2025 
2026   if (x->ops->setlocaltoglobalmapping) {
2027     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2028   } else {
2029     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2030     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2031   }
2032   PetscFunctionReturn(0);
2033 }
2034 
2035 
2036 /*@
2037    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2038 
2039    Not Collective
2040 
2041    Input Parameters:
2042 .  A - the matrix
2043 
2044    Output Parameters:
2045 + rmapping - row mapping
2046 - cmapping - column mapping
2047 
2048    Level: advanced
2049 
2050 
2051 .seealso:  MatSetValuesLocal()
2052 @*/
2053 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2054 {
2055   PetscFunctionBegin;
2056   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2057   PetscValidType(A,1);
2058   if (rmapping) PetscValidPointer(rmapping,2);
2059   if (cmapping) PetscValidPointer(cmapping,3);
2060   if (rmapping) *rmapping = A->rmap->mapping;
2061   if (cmapping) *cmapping = A->cmap->mapping;
2062   PetscFunctionReturn(0);
2063 }
2064 
2065 /*@
2066    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2067 
2068    Not Collective
2069 
2070    Input Parameters:
2071 .  A - the matrix
2072 
2073    Output Parameters:
2074 + rmap - row layout
2075 - cmap - column layout
2076 
2077    Level: advanced
2078 
2079 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2080 @*/
2081 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2082 {
2083   PetscFunctionBegin;
2084   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2085   PetscValidType(A,1);
2086   if (rmap) PetscValidPointer(rmap,2);
2087   if (cmap) PetscValidPointer(cmap,3);
2088   if (rmap) *rmap = A->rmap;
2089   if (cmap) *cmap = A->cmap;
2090   PetscFunctionReturn(0);
2091 }
2092 
2093 /*@C
2094    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2095    using a local ordering of the nodes.
2096 
2097    Not Collective
2098 
2099    Input Parameters:
2100 +  mat - the matrix
2101 .  nrow, irow - number of rows and their local indices
2102 .  ncol, icol - number of columns and their local indices
2103 .  y -  a logically two-dimensional array of values
2104 -  addv - either INSERT_VALUES or ADD_VALUES, where
2105    ADD_VALUES adds values to any existing entries, and
2106    INSERT_VALUES replaces existing entries with new values
2107 
2108    Notes:
2109    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2110       MatSetUp() before using this routine
2111 
2112    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2113 
2114    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2115    options cannot be mixed without intervening calls to the assembly
2116    routines.
2117 
2118    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2119    MUST be called after all calls to MatSetValuesLocal() have been completed.
2120 
2121    Level: intermediate
2122 
2123    Developer Notes:
2124     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2125                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2126 
2127 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2128            MatSetValueLocal()
2129 @*/
2130 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2131 {
2132   PetscErrorCode ierr;
2133 
2134   PetscFunctionBeginHot;
2135   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2136   PetscValidType(mat,1);
2137   MatCheckPreallocated(mat,1);
2138   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2139   PetscValidIntPointer(irow,3);
2140   PetscValidIntPointer(icol,5);
2141   if (mat->insertmode == NOT_SET_VALUES) {
2142     mat->insertmode = addv;
2143   }
2144 #if defined(PETSC_USE_DEBUG)
2145   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2146   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2147   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2148 #endif
2149 
2150   if (mat->assembled) {
2151     mat->was_assembled = PETSC_TRUE;
2152     mat->assembled     = PETSC_FALSE;
2153   }
2154   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2155   if (mat->ops->setvalueslocal) {
2156     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2157   } else {
2158     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2159     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2160       irowm = buf; icolm = buf+nrow;
2161     } else {
2162       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2163       irowm = bufr; icolm = bufc;
2164     }
2165     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2166     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2167     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2168     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2169   }
2170   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2171 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2172   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2173     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2174   }
2175 #endif
2176   PetscFunctionReturn(0);
2177 }
2178 
2179 /*@C
2180    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2181    using a local ordering of the nodes a block at a time.
2182 
2183    Not Collective
2184 
2185    Input Parameters:
2186 +  x - the matrix
2187 .  nrow, irow - number of rows and their local indices
2188 .  ncol, icol - number of columns and their local indices
2189 .  y -  a logically two-dimensional array of values
2190 -  addv - either INSERT_VALUES or ADD_VALUES, where
2191    ADD_VALUES adds values to any existing entries, and
2192    INSERT_VALUES replaces existing entries with new values
2193 
2194    Notes:
2195    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2196       MatSetUp() before using this routine
2197 
2198    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2199       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2200 
2201    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2202    options cannot be mixed without intervening calls to the assembly
2203    routines.
2204 
2205    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2206    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2207 
2208    Level: intermediate
2209 
2210    Developer Notes:
2211     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2212                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2213 
2214 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2215            MatSetValuesLocal(),  MatSetValuesBlocked()
2216 @*/
2217 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2218 {
2219   PetscErrorCode ierr;
2220 
2221   PetscFunctionBeginHot;
2222   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2223   PetscValidType(mat,1);
2224   MatCheckPreallocated(mat,1);
2225   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2226   PetscValidIntPointer(irow,3);
2227   PetscValidIntPointer(icol,5);
2228   PetscValidScalarPointer(y,6);
2229   if (mat->insertmode == NOT_SET_VALUES) {
2230     mat->insertmode = addv;
2231   }
2232 #if defined(PETSC_USE_DEBUG)
2233   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2234   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2235   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2236 #endif
2237 
2238   if (mat->assembled) {
2239     mat->was_assembled = PETSC_TRUE;
2240     mat->assembled     = PETSC_FALSE;
2241   }
2242 #if defined(PETSC_USE_DEBUG)
2243   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2244   if (mat->rmap->mapping) {
2245     PetscInt irbs, rbs;
2246     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2247     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2248     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2249   }
2250   if (mat->cmap->mapping) {
2251     PetscInt icbs, cbs;
2252     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2253     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2254     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2255   }
2256 #endif
2257   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2258   if (mat->ops->setvaluesblockedlocal) {
2259     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2260   } else {
2261     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2262     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2263       irowm = buf; icolm = buf + nrow;
2264     } else {
2265       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2266       irowm = bufr; icolm = bufc;
2267     }
2268     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2269     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2270     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2271     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2272   }
2273   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2274 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2275   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2276     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2277   }
2278 #endif
2279   PetscFunctionReturn(0);
2280 }
2281 
2282 /*@
2283    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2284 
2285    Collective on Mat
2286 
2287    Input Parameters:
2288 +  mat - the matrix
2289 -  x   - the vector to be multiplied
2290 
2291    Output Parameters:
2292 .  y - the result
2293 
2294    Notes:
2295    The vectors x and y cannot be the same.  I.e., one cannot
2296    call MatMult(A,y,y).
2297 
2298    Level: developer
2299 
2300 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2301 @*/
2302 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2303 {
2304   PetscErrorCode ierr;
2305 
2306   PetscFunctionBegin;
2307   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2308   PetscValidType(mat,1);
2309   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2310   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2311 
2312   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2313   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2314   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2315   MatCheckPreallocated(mat,1);
2316 
2317   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2318   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2319   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2320   PetscFunctionReturn(0);
2321 }
2322 
2323 /* --------------------------------------------------------*/
2324 /*@
2325    MatMult - Computes the matrix-vector product, y = Ax.
2326 
2327    Neighbor-wise Collective on Mat
2328 
2329    Input Parameters:
2330 +  mat - the matrix
2331 -  x   - the vector to be multiplied
2332 
2333    Output Parameters:
2334 .  y - the result
2335 
2336    Notes:
2337    The vectors x and y cannot be the same.  I.e., one cannot
2338    call MatMult(A,y,y).
2339 
2340    Level: beginner
2341 
2342 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2343 @*/
2344 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2345 {
2346   PetscErrorCode ierr;
2347 
2348   PetscFunctionBegin;
2349   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2350   PetscValidType(mat,1);
2351   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2352   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2353   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2354   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2355   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2356 #if !defined(PETSC_HAVE_CONSTRAINTS)
2357   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2358   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2359   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2360 #endif
2361   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2362   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2363   MatCheckPreallocated(mat,1);
2364 
2365   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2366   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2367   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2368   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2369   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2370   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2371   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2372   PetscFunctionReturn(0);
2373 }
2374 
2375 /*@
2376    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2377 
2378    Neighbor-wise Collective on Mat
2379 
2380    Input Parameters:
2381 +  mat - the matrix
2382 -  x   - the vector to be multiplied
2383 
2384    Output Parameters:
2385 .  y - the result
2386 
2387    Notes:
2388    The vectors x and y cannot be the same.  I.e., one cannot
2389    call MatMultTranspose(A,y,y).
2390 
2391    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2392    use MatMultHermitianTranspose()
2393 
2394    Level: beginner
2395 
2396 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2397 @*/
2398 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2399 {
2400   PetscErrorCode ierr;
2401 
2402   PetscFunctionBegin;
2403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2404   PetscValidType(mat,1);
2405   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2406   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2407 
2408   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2409   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2410   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2411 #if !defined(PETSC_HAVE_CONSTRAINTS)
2412   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2413   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2414 #endif
2415   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2416   MatCheckPreallocated(mat,1);
2417 
2418   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2419   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2420   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2421   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2422   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2423   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2424   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2425   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2426   PetscFunctionReturn(0);
2427 }
2428 
2429 /*@
2430    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2431 
2432    Neighbor-wise Collective on Mat
2433 
2434    Input Parameters:
2435 +  mat - the matrix
2436 -  x   - the vector to be multilplied
2437 
2438    Output Parameters:
2439 .  y - the result
2440 
2441    Notes:
2442    The vectors x and y cannot be the same.  I.e., one cannot
2443    call MatMultHermitianTranspose(A,y,y).
2444 
2445    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2446 
2447    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2448 
2449    Level: beginner
2450 
2451 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2452 @*/
2453 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2454 {
2455   PetscErrorCode ierr;
2456   Vec            w;
2457 
2458   PetscFunctionBegin;
2459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2460   PetscValidType(mat,1);
2461   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2462   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2463 
2464   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2465   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2466   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2467 #if !defined(PETSC_HAVE_CONSTRAINTS)
2468   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2469   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2470 #endif
2471   MatCheckPreallocated(mat,1);
2472 
2473   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2474   if (mat->ops->multhermitiantranspose) {
2475     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2476     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2477     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2478   } else {
2479     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2480     ierr = VecCopy(x,w);CHKERRQ(ierr);
2481     ierr = VecConjugate(w);CHKERRQ(ierr);
2482     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2483     ierr = VecDestroy(&w);CHKERRQ(ierr);
2484     ierr = VecConjugate(y);CHKERRQ(ierr);
2485   }
2486   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2487   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2488   PetscFunctionReturn(0);
2489 }
2490 
2491 /*@
2492     MatMultAdd -  Computes v3 = v2 + A * v1.
2493 
2494     Neighbor-wise Collective on Mat
2495 
2496     Input Parameters:
2497 +   mat - the matrix
2498 -   v1, v2 - the vectors
2499 
2500     Output Parameters:
2501 .   v3 - the result
2502 
2503     Notes:
2504     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2505     call MatMultAdd(A,v1,v2,v1).
2506 
2507     Level: beginner
2508 
2509 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2510 @*/
2511 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2512 {
2513   PetscErrorCode ierr;
2514 
2515   PetscFunctionBegin;
2516   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2517   PetscValidType(mat,1);
2518   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2519   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2520   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2521 
2522   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2523   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2524   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2525   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2526      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2527   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2528   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2529   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2530   MatCheckPreallocated(mat,1);
2531 
2532   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2533   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2534   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2535   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2536   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2537   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2538   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2539   PetscFunctionReturn(0);
2540 }
2541 
2542 /*@
2543    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2544 
2545    Neighbor-wise Collective on Mat
2546 
2547    Input Parameters:
2548 +  mat - the matrix
2549 -  v1, v2 - the vectors
2550 
2551    Output Parameters:
2552 .  v3 - the result
2553 
2554    Notes:
2555    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2556    call MatMultTransposeAdd(A,v1,v2,v1).
2557 
2558    Level: beginner
2559 
2560 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2561 @*/
2562 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2563 {
2564   PetscErrorCode ierr;
2565 
2566   PetscFunctionBegin;
2567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2568   PetscValidType(mat,1);
2569   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2570   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2571   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2572 
2573   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2574   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2575   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2576   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2577   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2578   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2579   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2580   MatCheckPreallocated(mat,1);
2581 
2582   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2583   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2584   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2585   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2586   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2587   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2588   PetscFunctionReturn(0);
2589 }
2590 
2591 /*@
2592    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2593 
2594    Neighbor-wise Collective on Mat
2595 
2596    Input Parameters:
2597 +  mat - the matrix
2598 -  v1, v2 - the vectors
2599 
2600    Output Parameters:
2601 .  v3 - the result
2602 
2603    Notes:
2604    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2605    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2606 
2607    Level: beginner
2608 
2609 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2610 @*/
2611 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2612 {
2613   PetscErrorCode ierr;
2614 
2615   PetscFunctionBegin;
2616   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2617   PetscValidType(mat,1);
2618   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2619   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2620   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2621 
2622   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2623   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2624   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2625   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2626   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2627   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2628   MatCheckPreallocated(mat,1);
2629 
2630   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2631   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2632   if (mat->ops->multhermitiantransposeadd) {
2633     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2634   } else {
2635     Vec w,z;
2636     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2637     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2638     ierr = VecConjugate(w);CHKERRQ(ierr);
2639     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2640     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2641     ierr = VecDestroy(&w);CHKERRQ(ierr);
2642     ierr = VecConjugate(z);CHKERRQ(ierr);
2643     if (v2 != v3) {
2644       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2645     } else {
2646       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2647     }
2648     ierr = VecDestroy(&z);CHKERRQ(ierr);
2649   }
2650   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2651   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2652   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2653   PetscFunctionReturn(0);
2654 }
2655 
2656 /*@
2657    MatMultConstrained - The inner multiplication routine for a
2658    constrained matrix P^T A P.
2659 
2660    Neighbor-wise Collective on Mat
2661 
2662    Input Parameters:
2663 +  mat - the matrix
2664 -  x   - the vector to be multilplied
2665 
2666    Output Parameters:
2667 .  y - the result
2668 
2669    Notes:
2670    The vectors x and y cannot be the same.  I.e., one cannot
2671    call MatMult(A,y,y).
2672 
2673    Level: beginner
2674 
2675 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2676 @*/
2677 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2678 {
2679   PetscErrorCode ierr;
2680 
2681   PetscFunctionBegin;
2682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2683   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2684   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2685   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2686   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2687   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2688   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2689   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2690   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2691 
2692   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2693   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2694   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2695   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2696   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2697   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2698   PetscFunctionReturn(0);
2699 }
2700 
2701 /*@
2702    MatMultTransposeConstrained - The inner multiplication routine for a
2703    constrained matrix P^T A^T P.
2704 
2705    Neighbor-wise Collective on Mat
2706 
2707    Input Parameters:
2708 +  mat - the matrix
2709 -  x   - the vector to be multilplied
2710 
2711    Output Parameters:
2712 .  y - the result
2713 
2714    Notes:
2715    The vectors x and y cannot be the same.  I.e., one cannot
2716    call MatMult(A,y,y).
2717 
2718    Level: beginner
2719 
2720 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2721 @*/
2722 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2723 {
2724   PetscErrorCode ierr;
2725 
2726   PetscFunctionBegin;
2727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2728   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2729   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2730   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2731   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2732   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2733   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2734   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2735 
2736   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2737   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2738   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2739   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2740   PetscFunctionReturn(0);
2741 }
2742 
2743 /*@C
2744    MatGetFactorType - gets the type of factorization it is
2745 
2746    Not Collective
2747 
2748    Input Parameters:
2749 .  mat - the matrix
2750 
2751    Output Parameters:
2752 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2753 
2754    Level: intermediate
2755 
2756 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2757 @*/
2758 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2759 {
2760   PetscFunctionBegin;
2761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2762   PetscValidType(mat,1);
2763   PetscValidPointer(t,2);
2764   *t = mat->factortype;
2765   PetscFunctionReturn(0);
2766 }
2767 
2768 /*@C
2769    MatSetFactorType - sets the type of factorization it is
2770 
2771    Logically Collective on Mat
2772 
2773    Input Parameters:
2774 +  mat - the matrix
2775 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2776 
2777    Level: intermediate
2778 
2779 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2780 @*/
2781 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2782 {
2783   PetscFunctionBegin;
2784   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2785   PetscValidType(mat,1);
2786   mat->factortype = t;
2787   PetscFunctionReturn(0);
2788 }
2789 
2790 /* ------------------------------------------------------------*/
2791 /*@C
2792    MatGetInfo - Returns information about matrix storage (number of
2793    nonzeros, memory, etc.).
2794 
2795    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2796 
2797    Input Parameters:
2798 .  mat - the matrix
2799 
2800    Output Parameters:
2801 +  flag - flag indicating the type of parameters to be returned
2802    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2803    MAT_GLOBAL_SUM - sum over all processors)
2804 -  info - matrix information context
2805 
2806    Notes:
2807    The MatInfo context contains a variety of matrix data, including
2808    number of nonzeros allocated and used, number of mallocs during
2809    matrix assembly, etc.  Additional information for factored matrices
2810    is provided (such as the fill ratio, number of mallocs during
2811    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2812    when using the runtime options
2813 $       -info -mat_view ::ascii_info
2814 
2815    Example for C/C++ Users:
2816    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2817    data within the MatInfo context.  For example,
2818 .vb
2819       MatInfo info;
2820       Mat     A;
2821       double  mal, nz_a, nz_u;
2822 
2823       MatGetInfo(A,MAT_LOCAL,&info);
2824       mal  = info.mallocs;
2825       nz_a = info.nz_allocated;
2826 .ve
2827 
2828    Example for Fortran Users:
2829    Fortran users should declare info as a double precision
2830    array of dimension MAT_INFO_SIZE, and then extract the parameters
2831    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2832    a complete list of parameter names.
2833 .vb
2834       double  precision info(MAT_INFO_SIZE)
2835       double  precision mal, nz_a
2836       Mat     A
2837       integer ierr
2838 
2839       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2840       mal = info(MAT_INFO_MALLOCS)
2841       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2842 .ve
2843 
2844     Level: intermediate
2845 
2846     Developer Note: fortran interface is not autogenerated as the f90
2847     interface defintion cannot be generated correctly [due to MatInfo]
2848 
2849 .seealso: MatStashGetInfo()
2850 
2851 @*/
2852 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2853 {
2854   PetscErrorCode ierr;
2855 
2856   PetscFunctionBegin;
2857   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2858   PetscValidType(mat,1);
2859   PetscValidPointer(info,3);
2860   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2861   MatCheckPreallocated(mat,1);
2862   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2863   PetscFunctionReturn(0);
2864 }
2865 
2866 /*
2867    This is used by external packages where it is not easy to get the info from the actual
2868    matrix factorization.
2869 */
2870 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2871 {
2872   PetscErrorCode ierr;
2873 
2874   PetscFunctionBegin;
2875   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2876   PetscFunctionReturn(0);
2877 }
2878 
2879 /* ----------------------------------------------------------*/
2880 
2881 /*@C
2882    MatLUFactor - Performs in-place LU factorization of matrix.
2883 
2884    Collective on Mat
2885 
2886    Input Parameters:
2887 +  mat - the matrix
2888 .  row - row permutation
2889 .  col - column permutation
2890 -  info - options for factorization, includes
2891 $          fill - expected fill as ratio of original fill.
2892 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2893 $                   Run with the option -info to determine an optimal value to use
2894 
2895    Notes:
2896    Most users should employ the simplified KSP interface for linear solvers
2897    instead of working directly with matrix algebra routines such as this.
2898    See, e.g., KSPCreate().
2899 
2900    This changes the state of the matrix to a factored matrix; it cannot be used
2901    for example with MatSetValues() unless one first calls MatSetUnfactored().
2902 
2903    Level: developer
2904 
2905 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2906           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2907 
2908     Developer Note: fortran interface is not autogenerated as the f90
2909     interface defintion cannot be generated correctly [due to MatFactorInfo]
2910 
2911 @*/
2912 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2913 {
2914   PetscErrorCode ierr;
2915   MatFactorInfo  tinfo;
2916 
2917   PetscFunctionBegin;
2918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2919   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2920   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2921   if (info) PetscValidPointer(info,4);
2922   PetscValidType(mat,1);
2923   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2924   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2925   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2926   MatCheckPreallocated(mat,1);
2927   if (!info) {
2928     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2929     info = &tinfo;
2930   }
2931 
2932   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2933   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2934   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2935   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2936   PetscFunctionReturn(0);
2937 }
2938 
2939 /*@C
2940    MatILUFactor - Performs in-place ILU factorization of matrix.
2941 
2942    Collective on Mat
2943 
2944    Input Parameters:
2945 +  mat - the matrix
2946 .  row - row permutation
2947 .  col - column permutation
2948 -  info - structure containing
2949 $      levels - number of levels of fill.
2950 $      expected fill - as ratio of original fill.
2951 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2952                 missing diagonal entries)
2953 
2954    Notes:
2955    Probably really in-place only when level of fill is zero, otherwise allocates
2956    new space to store factored matrix and deletes previous memory.
2957 
2958    Most users should employ the simplified KSP interface for linear solvers
2959    instead of working directly with matrix algebra routines such as this.
2960    See, e.g., KSPCreate().
2961 
2962    Level: developer
2963 
2964 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2965 
2966     Developer Note: fortran interface is not autogenerated as the f90
2967     interface defintion cannot be generated correctly [due to MatFactorInfo]
2968 
2969 @*/
2970 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2971 {
2972   PetscErrorCode ierr;
2973 
2974   PetscFunctionBegin;
2975   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2976   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2977   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2978   PetscValidPointer(info,4);
2979   PetscValidType(mat,1);
2980   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2981   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2982   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2983   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2984   MatCheckPreallocated(mat,1);
2985 
2986   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2987   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2988   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2989   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2990   PetscFunctionReturn(0);
2991 }
2992 
2993 /*@C
2994    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2995    Call this routine before calling MatLUFactorNumeric().
2996 
2997    Collective on Mat
2998 
2999    Input Parameters:
3000 +  fact - the factor matrix obtained with MatGetFactor()
3001 .  mat - the matrix
3002 .  row, col - row and column permutations
3003 -  info - options for factorization, includes
3004 $          fill - expected fill as ratio of original fill.
3005 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3006 $                   Run with the option -info to determine an optimal value to use
3007 
3008 
3009    Notes:
3010     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3011 
3012    Most users should employ the simplified KSP interface for linear solvers
3013    instead of working directly with matrix algebra routines such as this.
3014    See, e.g., KSPCreate().
3015 
3016    Level: developer
3017 
3018 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3019 
3020     Developer Note: fortran interface is not autogenerated as the f90
3021     interface defintion cannot be generated correctly [due to MatFactorInfo]
3022 
3023 @*/
3024 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3025 {
3026   PetscErrorCode ierr;
3027 
3028   PetscFunctionBegin;
3029   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3030   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3031   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3032   if (info) PetscValidPointer(info,4);
3033   PetscValidType(mat,1);
3034   PetscValidPointer(fact,5);
3035   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3036   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3037   if (!(fact)->ops->lufactorsymbolic) {
3038     MatSolverType spackage;
3039     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3040     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3041   }
3042   MatCheckPreallocated(mat,2);
3043 
3044   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3045   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3046   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3047   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3048   PetscFunctionReturn(0);
3049 }
3050 
3051 /*@C
3052    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3053    Call this routine after first calling MatLUFactorSymbolic().
3054 
3055    Collective on Mat
3056 
3057    Input Parameters:
3058 +  fact - the factor matrix obtained with MatGetFactor()
3059 .  mat - the matrix
3060 -  info - options for factorization
3061 
3062    Notes:
3063    See MatLUFactor() for in-place factorization.  See
3064    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3065 
3066    Most users should employ the simplified KSP interface for linear solvers
3067    instead of working directly with matrix algebra routines such as this.
3068    See, e.g., KSPCreate().
3069 
3070    Level: developer
3071 
3072 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3073 
3074     Developer Note: fortran interface is not autogenerated as the f90
3075     interface defintion cannot be generated correctly [due to MatFactorInfo]
3076 
3077 @*/
3078 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3079 {
3080   PetscErrorCode ierr;
3081 
3082   PetscFunctionBegin;
3083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3084   PetscValidType(mat,1);
3085   PetscValidPointer(fact,2);
3086   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3087   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3088   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3089 
3090   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3091   MatCheckPreallocated(mat,2);
3092   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3093   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3094   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3095   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3096   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3097   PetscFunctionReturn(0);
3098 }
3099 
3100 /*@C
3101    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3102    symmetric matrix.
3103 
3104    Collective on Mat
3105 
3106    Input Parameters:
3107 +  mat - the matrix
3108 .  perm - row and column permutations
3109 -  f - expected fill as ratio of original fill
3110 
3111    Notes:
3112    See MatLUFactor() for the nonsymmetric case.  See also
3113    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3114 
3115    Most users should employ the simplified KSP interface for linear solvers
3116    instead of working directly with matrix algebra routines such as this.
3117    See, e.g., KSPCreate().
3118 
3119    Level: developer
3120 
3121 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3122           MatGetOrdering()
3123 
3124     Developer Note: fortran interface is not autogenerated as the f90
3125     interface defintion cannot be generated correctly [due to MatFactorInfo]
3126 
3127 @*/
3128 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3129 {
3130   PetscErrorCode ierr;
3131 
3132   PetscFunctionBegin;
3133   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3134   PetscValidType(mat,1);
3135   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3136   if (info) PetscValidPointer(info,3);
3137   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3138   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3139   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3140   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3141   MatCheckPreallocated(mat,1);
3142 
3143   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3144   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3145   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3146   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3147   PetscFunctionReturn(0);
3148 }
3149 
3150 /*@C
3151    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3152    of a symmetric matrix.
3153 
3154    Collective on Mat
3155 
3156    Input Parameters:
3157 +  fact - the factor matrix obtained with MatGetFactor()
3158 .  mat - the matrix
3159 .  perm - row and column permutations
3160 -  info - options for factorization, includes
3161 $          fill - expected fill as ratio of original fill.
3162 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3163 $                   Run with the option -info to determine an optimal value to use
3164 
3165    Notes:
3166    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3167    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3168 
3169    Most users should employ the simplified KSP interface for linear solvers
3170    instead of working directly with matrix algebra routines such as this.
3171    See, e.g., KSPCreate().
3172 
3173    Level: developer
3174 
3175 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3176           MatGetOrdering()
3177 
3178     Developer Note: fortran interface is not autogenerated as the f90
3179     interface defintion cannot be generated correctly [due to MatFactorInfo]
3180 
3181 @*/
3182 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3183 {
3184   PetscErrorCode ierr;
3185 
3186   PetscFunctionBegin;
3187   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3188   PetscValidType(mat,1);
3189   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3190   if (info) PetscValidPointer(info,3);
3191   PetscValidPointer(fact,4);
3192   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3193   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3194   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3195   if (!(fact)->ops->choleskyfactorsymbolic) {
3196     MatSolverType spackage;
3197     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3198     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3199   }
3200   MatCheckPreallocated(mat,2);
3201 
3202   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3203   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3204   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3205   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3206   PetscFunctionReturn(0);
3207 }
3208 
3209 /*@C
3210    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3211    of a symmetric matrix. Call this routine after first calling
3212    MatCholeskyFactorSymbolic().
3213 
3214    Collective on Mat
3215 
3216    Input Parameters:
3217 +  fact - the factor matrix obtained with MatGetFactor()
3218 .  mat - the initial matrix
3219 .  info - options for factorization
3220 -  fact - the symbolic factor of mat
3221 
3222 
3223    Notes:
3224    Most users should employ the simplified KSP interface for linear solvers
3225    instead of working directly with matrix algebra routines such as this.
3226    See, e.g., KSPCreate().
3227 
3228    Level: developer
3229 
3230 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3231 
3232     Developer Note: fortran interface is not autogenerated as the f90
3233     interface defintion cannot be generated correctly [due to MatFactorInfo]
3234 
3235 @*/
3236 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3237 {
3238   PetscErrorCode ierr;
3239 
3240   PetscFunctionBegin;
3241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3242   PetscValidType(mat,1);
3243   PetscValidPointer(fact,2);
3244   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3245   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3246   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3247   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3248   MatCheckPreallocated(mat,2);
3249 
3250   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3251   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3252   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3253   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3254   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3255   PetscFunctionReturn(0);
3256 }
3257 
3258 /* ----------------------------------------------------------------*/
3259 /*@
3260    MatSolve - Solves A x = b, given a factored matrix.
3261 
3262    Neighbor-wise Collective on Mat
3263 
3264    Input Parameters:
3265 +  mat - the factored matrix
3266 -  b - the right-hand-side vector
3267 
3268    Output Parameter:
3269 .  x - the result vector
3270 
3271    Notes:
3272    The vectors b and x cannot be the same.  I.e., one cannot
3273    call MatSolve(A,x,x).
3274 
3275    Notes:
3276    Most users should employ the simplified KSP interface for linear solvers
3277    instead of working directly with matrix algebra routines such as this.
3278    See, e.g., KSPCreate().
3279 
3280    Level: developer
3281 
3282 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3283 @*/
3284 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3285 {
3286   PetscErrorCode ierr;
3287 
3288   PetscFunctionBegin;
3289   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3290   PetscValidType(mat,1);
3291   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3292   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3293   PetscCheckSameComm(mat,1,b,2);
3294   PetscCheckSameComm(mat,1,x,3);
3295   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3296   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3297   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3298   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3299   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3300   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3301   MatCheckPreallocated(mat,1);
3302 
3303   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3304   if (mat->factorerrortype) {
3305     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3306     ierr = VecSetInf(x);CHKERRQ(ierr);
3307   } else {
3308     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3309     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3310   }
3311   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3312   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3313   PetscFunctionReturn(0);
3314 }
3315 
3316 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3317 {
3318   PetscErrorCode ierr;
3319   Vec            b,x;
3320   PetscInt       m,N,i;
3321   PetscScalar    *bb,*xx;
3322 
3323   PetscFunctionBegin;
3324   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3325   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3326   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3327   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3328   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3329   for (i=0; i<N; i++) {
3330     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3331     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3332     if (trans) {
3333       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3334     } else {
3335       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3336     }
3337     ierr = VecResetArray(x);CHKERRQ(ierr);
3338     ierr = VecResetArray(b);CHKERRQ(ierr);
3339   }
3340   ierr = VecDestroy(&b);CHKERRQ(ierr);
3341   ierr = VecDestroy(&x);CHKERRQ(ierr);
3342   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3343   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3344   PetscFunctionReturn(0);
3345 }
3346 
3347 /*@
3348    MatMatSolve - Solves A X = B, given a factored matrix.
3349 
3350    Neighbor-wise Collective on Mat
3351 
3352    Input Parameters:
3353 +  A - the factored matrix
3354 -  B - the right-hand-side matrix  (dense matrix)
3355 
3356    Output Parameter:
3357 .  X - the result matrix (dense matrix)
3358 
3359    Notes:
3360    The matrices b and x cannot be the same.  I.e., one cannot
3361    call MatMatSolve(A,x,x).
3362 
3363    Notes:
3364    Most users should usually employ the simplified KSP interface for linear solvers
3365    instead of working directly with matrix algebra routines such as this.
3366    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3367    at a time.
3368 
3369    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3370    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3371 
3372    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3373 
3374    Level: developer
3375 
3376 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3377 @*/
3378 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3379 {
3380   PetscErrorCode ierr;
3381 
3382   PetscFunctionBegin;
3383   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3384   PetscValidType(A,1);
3385   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3386   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3387   PetscCheckSameComm(A,1,B,2);
3388   PetscCheckSameComm(A,1,X,3);
3389   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3390   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3391   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3392   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3393   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3394   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3395   MatCheckPreallocated(A,1);
3396 
3397   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3398   if (!A->ops->matsolve) {
3399     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3400     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3401   } else {
3402     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3403   }
3404   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3405   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3406   PetscFunctionReturn(0);
3407 }
3408 
3409 /*@
3410    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3411 
3412    Neighbor-wise Collective on Mat
3413 
3414    Input Parameters:
3415 +  A - the factored matrix
3416 -  B - the right-hand-side matrix  (dense matrix)
3417 
3418    Output Parameter:
3419 .  X - the result matrix (dense matrix)
3420 
3421    Notes:
3422    The matrices B and X cannot be the same.  I.e., one cannot
3423    call MatMatSolveTranspose(A,X,X).
3424 
3425    Notes:
3426    Most users should usually employ the simplified KSP interface for linear solvers
3427    instead of working directly with matrix algebra routines such as this.
3428    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3429    at a time.
3430 
3431    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3432 
3433    Level: developer
3434 
3435 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3436 @*/
3437 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3438 {
3439   PetscErrorCode ierr;
3440 
3441   PetscFunctionBegin;
3442   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3443   PetscValidType(A,1);
3444   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3445   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3446   PetscCheckSameComm(A,1,B,2);
3447   PetscCheckSameComm(A,1,X,3);
3448   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3449   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3450   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3451   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3452   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3453   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3454   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3455   MatCheckPreallocated(A,1);
3456 
3457   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3458   if (!A->ops->matsolvetranspose) {
3459     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3460     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3461   } else {
3462     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3463   }
3464   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3465   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3466   PetscFunctionReturn(0);
3467 }
3468 
3469 /*@
3470    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3471 
3472    Neighbor-wise Collective on Mat
3473 
3474    Input Parameters:
3475 +  A - the factored matrix
3476 -  Bt - the transpose of right-hand-side matrix
3477 
3478    Output Parameter:
3479 .  X - the result matrix (dense matrix)
3480 
3481    Notes:
3482    Most users should usually employ the simplified KSP interface for linear solvers
3483    instead of working directly with matrix algebra routines such as this.
3484    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3485    at a time.
3486 
3487    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().
3488 
3489    Level: developer
3490 
3491 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3492 @*/
3493 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3494 {
3495   PetscErrorCode ierr;
3496 
3497   PetscFunctionBegin;
3498   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3499   PetscValidType(A,1);
3500   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3501   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3502   PetscCheckSameComm(A,1,Bt,2);
3503   PetscCheckSameComm(A,1,X,3);
3504 
3505   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3506   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3507   if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3508   if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3509   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3510   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511   MatCheckPreallocated(A,1);
3512 
3513   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3514   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3515   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3516   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3517   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3518   PetscFunctionReturn(0);
3519 }
3520 
3521 /*@
3522    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3523                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3524 
3525    Neighbor-wise Collective on Mat
3526 
3527    Input Parameters:
3528 +  mat - the factored matrix
3529 -  b - the right-hand-side vector
3530 
3531    Output Parameter:
3532 .  x - the result vector
3533 
3534    Notes:
3535    MatSolve() should be used for most applications, as it performs
3536    a forward solve followed by a backward solve.
3537 
3538    The vectors b and x cannot be the same,  i.e., one cannot
3539    call MatForwardSolve(A,x,x).
3540 
3541    For matrix in seqsbaij format with block size larger than 1,
3542    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3543    MatForwardSolve() solves U^T*D y = b, and
3544    MatBackwardSolve() solves U x = y.
3545    Thus they do not provide a symmetric preconditioner.
3546 
3547    Most users should employ the simplified KSP interface for linear solvers
3548    instead of working directly with matrix algebra routines such as this.
3549    See, e.g., KSPCreate().
3550 
3551    Level: developer
3552 
3553 .seealso: MatSolve(), MatBackwardSolve()
3554 @*/
3555 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3556 {
3557   PetscErrorCode ierr;
3558 
3559   PetscFunctionBegin;
3560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3561   PetscValidType(mat,1);
3562   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3563   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3564   PetscCheckSameComm(mat,1,b,2);
3565   PetscCheckSameComm(mat,1,x,3);
3566   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3567   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3568   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3569   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3570   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3571   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3572   MatCheckPreallocated(mat,1);
3573 
3574   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3575   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3576   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3577   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3578   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3579   PetscFunctionReturn(0);
3580 }
3581 
3582 /*@
3583    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3584                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3585 
3586    Neighbor-wise Collective on Mat
3587 
3588    Input Parameters:
3589 +  mat - the factored matrix
3590 -  b - the right-hand-side vector
3591 
3592    Output Parameter:
3593 .  x - the result vector
3594 
3595    Notes:
3596    MatSolve() should be used for most applications, as it performs
3597    a forward solve followed by a backward solve.
3598 
3599    The vectors b and x cannot be the same.  I.e., one cannot
3600    call MatBackwardSolve(A,x,x).
3601 
3602    For matrix in seqsbaij format with block size larger than 1,
3603    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3604    MatForwardSolve() solves U^T*D y = b, and
3605    MatBackwardSolve() solves U x = y.
3606    Thus they do not provide a symmetric preconditioner.
3607 
3608    Most users should employ the simplified KSP interface for linear solvers
3609    instead of working directly with matrix algebra routines such as this.
3610    See, e.g., KSPCreate().
3611 
3612    Level: developer
3613 
3614 .seealso: MatSolve(), MatForwardSolve()
3615 @*/
3616 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3617 {
3618   PetscErrorCode ierr;
3619 
3620   PetscFunctionBegin;
3621   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3622   PetscValidType(mat,1);
3623   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3624   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3625   PetscCheckSameComm(mat,1,b,2);
3626   PetscCheckSameComm(mat,1,x,3);
3627   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3628   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3629   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3630   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3631   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3632   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3633   MatCheckPreallocated(mat,1);
3634 
3635   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3636   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3637   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3638   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3639   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3640   PetscFunctionReturn(0);
3641 }
3642 
3643 /*@
3644    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3645 
3646    Neighbor-wise Collective on Mat
3647 
3648    Input Parameters:
3649 +  mat - the factored matrix
3650 .  b - the right-hand-side vector
3651 -  y - the vector to be added to
3652 
3653    Output Parameter:
3654 .  x - the result vector
3655 
3656    Notes:
3657    The vectors b and x cannot be the same.  I.e., one cannot
3658    call MatSolveAdd(A,x,y,x).
3659 
3660    Most users should employ the simplified KSP interface for linear solvers
3661    instead of working directly with matrix algebra routines such as this.
3662    See, e.g., KSPCreate().
3663 
3664    Level: developer
3665 
3666 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3667 @*/
3668 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3669 {
3670   PetscScalar    one = 1.0;
3671   Vec            tmp;
3672   PetscErrorCode ierr;
3673 
3674   PetscFunctionBegin;
3675   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3676   PetscValidType(mat,1);
3677   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3678   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3679   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3680   PetscCheckSameComm(mat,1,b,2);
3681   PetscCheckSameComm(mat,1,y,2);
3682   PetscCheckSameComm(mat,1,x,3);
3683   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3684   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3685   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3686   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3687   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3688   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3689   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3690   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3691   MatCheckPreallocated(mat,1);
3692 
3693   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3694   if (mat->ops->solveadd) {
3695     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3696   } else {
3697     /* do the solve then the add manually */
3698     if (x != y) {
3699       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3700       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3701     } else {
3702       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3703       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3704       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3705       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3706       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3707       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3708     }
3709   }
3710   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3711   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3712   PetscFunctionReturn(0);
3713 }
3714 
3715 /*@
3716    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3717 
3718    Neighbor-wise Collective on Mat
3719 
3720    Input Parameters:
3721 +  mat - the factored matrix
3722 -  b - the right-hand-side vector
3723 
3724    Output Parameter:
3725 .  x - the result vector
3726 
3727    Notes:
3728    The vectors b and x cannot be the same.  I.e., one cannot
3729    call MatSolveTranspose(A,x,x).
3730 
3731    Most users should employ the simplified KSP interface for linear solvers
3732    instead of working directly with matrix algebra routines such as this.
3733    See, e.g., KSPCreate().
3734 
3735    Level: developer
3736 
3737 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3738 @*/
3739 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3740 {
3741   PetscErrorCode ierr;
3742 
3743   PetscFunctionBegin;
3744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3745   PetscValidType(mat,1);
3746   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3747   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3748   PetscCheckSameComm(mat,1,b,2);
3749   PetscCheckSameComm(mat,1,x,3);
3750   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3751   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3752   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3753   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3754   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3755   MatCheckPreallocated(mat,1);
3756   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3757   if (mat->factorerrortype) {
3758     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3759     ierr = VecSetInf(x);CHKERRQ(ierr);
3760   } else {
3761     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3762     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3763   }
3764   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3765   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3766   PetscFunctionReturn(0);
3767 }
3768 
3769 /*@
3770    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3771                       factored matrix.
3772 
3773    Neighbor-wise Collective on Mat
3774 
3775    Input Parameters:
3776 +  mat - the factored matrix
3777 .  b - the right-hand-side vector
3778 -  y - the vector to be added to
3779 
3780    Output Parameter:
3781 .  x - the result vector
3782 
3783    Notes:
3784    The vectors b and x cannot be the same.  I.e., one cannot
3785    call MatSolveTransposeAdd(A,x,y,x).
3786 
3787    Most users should employ the simplified KSP interface for linear solvers
3788    instead of working directly with matrix algebra routines such as this.
3789    See, e.g., KSPCreate().
3790 
3791    Level: developer
3792 
3793 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3794 @*/
3795 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3796 {
3797   PetscScalar    one = 1.0;
3798   PetscErrorCode ierr;
3799   Vec            tmp;
3800 
3801   PetscFunctionBegin;
3802   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3803   PetscValidType(mat,1);
3804   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3805   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3806   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3807   PetscCheckSameComm(mat,1,b,2);
3808   PetscCheckSameComm(mat,1,y,3);
3809   PetscCheckSameComm(mat,1,x,4);
3810   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3811   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3812   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3813   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3814   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3815   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3816   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3817   MatCheckPreallocated(mat,1);
3818 
3819   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3820   if (mat->ops->solvetransposeadd) {
3821     if (mat->factorerrortype) {
3822       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3823       ierr = VecSetInf(x);CHKERRQ(ierr);
3824     } else {
3825       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3826     }
3827   } else {
3828     /* do the solve then the add manually */
3829     if (x != y) {
3830       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3831       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3832     } else {
3833       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3834       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3835       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3836       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3837       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3838       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3839     }
3840   }
3841   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3842   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3843   PetscFunctionReturn(0);
3844 }
3845 /* ----------------------------------------------------------------*/
3846 
3847 /*@
3848    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3849 
3850    Neighbor-wise Collective on Mat
3851 
3852    Input Parameters:
3853 +  mat - the matrix
3854 .  b - the right hand side
3855 .  omega - the relaxation factor
3856 .  flag - flag indicating the type of SOR (see below)
3857 .  shift -  diagonal shift
3858 .  its - the number of iterations
3859 -  lits - the number of local iterations
3860 
3861    Output Parameters:
3862 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3863 
3864    SOR Flags:
3865 +     SOR_FORWARD_SWEEP - forward SOR
3866 .     SOR_BACKWARD_SWEEP - backward SOR
3867 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3868 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3869 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3870 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3871 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3872          upper/lower triangular part of matrix to
3873          vector (with omega)
3874 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
3875 
3876    Notes:
3877    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3878    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3879    on each processor.
3880 
3881    Application programmers will not generally use MatSOR() directly,
3882    but instead will employ the KSP/PC interface.
3883 
3884    Notes:
3885     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3886 
3887    Notes for Advanced Users:
3888    The flags are implemented as bitwise inclusive or operations.
3889    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3890    to specify a zero initial guess for SSOR.
3891 
3892    Most users should employ the simplified KSP interface for linear solvers
3893    instead of working directly with matrix algebra routines such as this.
3894    See, e.g., KSPCreate().
3895 
3896    Vectors x and b CANNOT be the same
3897 
3898    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3899 
3900    Level: developer
3901 
3902 @*/
3903 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3904 {
3905   PetscErrorCode ierr;
3906 
3907   PetscFunctionBegin;
3908   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3909   PetscValidType(mat,1);
3910   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3911   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3912   PetscCheckSameComm(mat,1,b,2);
3913   PetscCheckSameComm(mat,1,x,8);
3914   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3915   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3916   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3917   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3918   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3919   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3920   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3921   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3922   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3923 
3924   MatCheckPreallocated(mat,1);
3925   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3926   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3927   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3928   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3929   PetscFunctionReturn(0);
3930 }
3931 
3932 /*
3933       Default matrix copy routine.
3934 */
3935 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3936 {
3937   PetscErrorCode    ierr;
3938   PetscInt          i,rstart = 0,rend = 0,nz;
3939   const PetscInt    *cwork;
3940   const PetscScalar *vwork;
3941 
3942   PetscFunctionBegin;
3943   if (B->assembled) {
3944     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3945   }
3946   if (str == SAME_NONZERO_PATTERN) {
3947     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3948     for (i=rstart; i<rend; i++) {
3949       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3950       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3951       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3952     }
3953   } else {
3954     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
3955   }
3956   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3957   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3958   PetscFunctionReturn(0);
3959 }
3960 
3961 /*@
3962    MatCopy - Copies a matrix to another matrix.
3963 
3964    Collective on Mat
3965 
3966    Input Parameters:
3967 +  A - the matrix
3968 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3969 
3970    Output Parameter:
3971 .  B - where the copy is put
3972 
3973    Notes:
3974    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3975    same nonzero pattern or the routine will crash.
3976 
3977    MatCopy() copies the matrix entries of a matrix to another existing
3978    matrix (after first zeroing the second matrix).  A related routine is
3979    MatConvert(), which first creates a new matrix and then copies the data.
3980 
3981    Level: intermediate
3982 
3983 .seealso: MatConvert(), MatDuplicate()
3984 
3985 @*/
3986 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3987 {
3988   PetscErrorCode ierr;
3989   PetscInt       i;
3990 
3991   PetscFunctionBegin;
3992   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3993   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3994   PetscValidType(A,1);
3995   PetscValidType(B,2);
3996   PetscCheckSameComm(A,1,B,2);
3997   MatCheckPreallocated(B,2);
3998   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3999   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4000   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4001   MatCheckPreallocated(A,1);
4002   if (A == B) PetscFunctionReturn(0);
4003 
4004   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4005   if (A->ops->copy) {
4006     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4007   } else { /* generic conversion */
4008     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4009   }
4010 
4011   B->stencil.dim = A->stencil.dim;
4012   B->stencil.noc = A->stencil.noc;
4013   for (i=0; i<=A->stencil.dim; i++) {
4014     B->stencil.dims[i]   = A->stencil.dims[i];
4015     B->stencil.starts[i] = A->stencil.starts[i];
4016   }
4017 
4018   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4019   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4020   PetscFunctionReturn(0);
4021 }
4022 
4023 /*@C
4024    MatConvert - Converts a matrix to another matrix, either of the same
4025    or different type.
4026 
4027    Collective on Mat
4028 
4029    Input Parameters:
4030 +  mat - the matrix
4031 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4032    same type as the original matrix.
4033 -  reuse - denotes if the destination matrix is to be created or reused.
4034    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
4035    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).
4036 
4037    Output Parameter:
4038 .  M - pointer to place new matrix
4039 
4040    Notes:
4041    MatConvert() first creates a new matrix and then copies the data from
4042    the first matrix.  A related routine is MatCopy(), which copies the matrix
4043    entries of one matrix to another already existing matrix context.
4044 
4045    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4046    the MPI communicator of the generated matrix is always the same as the communicator
4047    of the input matrix.
4048 
4049    Level: intermediate
4050 
4051 .seealso: MatCopy(), MatDuplicate()
4052 @*/
4053 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4054 {
4055   PetscErrorCode ierr;
4056   PetscBool      sametype,issame,flg;
4057   char           convname[256],mtype[256];
4058   Mat            B;
4059 
4060   PetscFunctionBegin;
4061   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4062   PetscValidType(mat,1);
4063   PetscValidPointer(M,3);
4064   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4065   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4066   MatCheckPreallocated(mat,1);
4067 
4068   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4069   if (flg) {
4070     newtype = mtype;
4071   }
4072   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4073   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4074   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4075   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4076 
4077   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4078 
4079   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4080     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4081   } else {
4082     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4083     const char     *prefix[3] = {"seq","mpi",""};
4084     PetscInt       i;
4085     /*
4086        Order of precedence:
4087        0) See if newtype is a superclass of the current matrix.
4088        1) See if a specialized converter is known to the current matrix.
4089        2) See if a specialized converter is known to the desired matrix class.
4090        3) See if a good general converter is registered for the desired class
4091           (as of 6/27/03 only MATMPIADJ falls into this category).
4092        4) See if a good general converter is known for the current matrix.
4093        5) Use a really basic converter.
4094     */
4095 
4096     /* 0) See if newtype is a superclass of the current matrix.
4097           i.e mat is mpiaij and newtype is aij */
4098     for (i=0; i<2; i++) {
4099       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4100       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4101       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4102       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4103       if (flg) {
4104         if (reuse == MAT_INPLACE_MATRIX) {
4105           PetscFunctionReturn(0);
4106         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4107           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4108           PetscFunctionReturn(0);
4109         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4110           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4111           PetscFunctionReturn(0);
4112         }
4113       }
4114     }
4115     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4116     for (i=0; i<3; i++) {
4117       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4118       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4119       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4120       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4121       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4122       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4123       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4124       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4125       if (conv) goto foundconv;
4126     }
4127 
4128     /* 2)  See if a specialized converter is known to the desired matrix class. */
4129     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4130     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4131     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4132     for (i=0; i<3; i++) {
4133       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4134       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4135       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4136       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4137       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4138       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4139       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4140       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4141       if (conv) {
4142         ierr = MatDestroy(&B);CHKERRQ(ierr);
4143         goto foundconv;
4144       }
4145     }
4146 
4147     /* 3) See if a good general converter is registered for the desired class */
4148     conv = B->ops->convertfrom;
4149     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4150     ierr = MatDestroy(&B);CHKERRQ(ierr);
4151     if (conv) goto foundconv;
4152 
4153     /* 4) See if a good general converter is known for the current matrix */
4154     if (mat->ops->convert) {
4155       conv = mat->ops->convert;
4156     }
4157     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4158     if (conv) goto foundconv;
4159 
4160     /* 5) Use a really basic converter. */
4161     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4162     conv = MatConvert_Basic;
4163 
4164 foundconv:
4165     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4166     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4167     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4168       /* the block sizes must be same if the mappings are copied over */
4169       (*M)->rmap->bs = mat->rmap->bs;
4170       (*M)->cmap->bs = mat->cmap->bs;
4171       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4172       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4173       (*M)->rmap->mapping = mat->rmap->mapping;
4174       (*M)->cmap->mapping = mat->cmap->mapping;
4175     }
4176     (*M)->stencil.dim = mat->stencil.dim;
4177     (*M)->stencil.noc = mat->stencil.noc;
4178     for (i=0; i<=mat->stencil.dim; i++) {
4179       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4180       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4181     }
4182     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4183   }
4184   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4185 
4186   /* Copy Mat options */
4187   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4188   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4189   PetscFunctionReturn(0);
4190 }
4191 
4192 /*@C
4193    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4194 
4195    Not Collective
4196 
4197    Input Parameter:
4198 .  mat - the matrix, must be a factored matrix
4199 
4200    Output Parameter:
4201 .   type - the string name of the package (do not free this string)
4202 
4203    Notes:
4204       In Fortran you pass in a empty string and the package name will be copied into it.
4205     (Make sure the string is long enough)
4206 
4207    Level: intermediate
4208 
4209 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4210 @*/
4211 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4212 {
4213   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4214 
4215   PetscFunctionBegin;
4216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4217   PetscValidType(mat,1);
4218   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4219   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4220   if (!conv) {
4221     *type = MATSOLVERPETSC;
4222   } else {
4223     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4224   }
4225   PetscFunctionReturn(0);
4226 }
4227 
4228 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4229 struct _MatSolverTypeForSpecifcType {
4230   MatType                        mtype;
4231   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4232   MatSolverTypeForSpecifcType next;
4233 };
4234 
4235 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4236 struct _MatSolverTypeHolder {
4237   char                           *name;
4238   MatSolverTypeForSpecifcType handlers;
4239   MatSolverTypeHolder         next;
4240 };
4241 
4242 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4243 
4244 /*@C
4245    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4246 
4247    Input Parameters:
4248 +    package - name of the package, for example petsc or superlu
4249 .    mtype - the matrix type that works with this package
4250 .    ftype - the type of factorization supported by the package
4251 -    getfactor - routine that will create the factored matrix ready to be used
4252 
4253     Level: intermediate
4254 
4255 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4256 @*/
4257 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4258 {
4259   PetscErrorCode              ierr;
4260   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4261   PetscBool                   flg;
4262   MatSolverTypeForSpecifcType inext,iprev = NULL;
4263 
4264   PetscFunctionBegin;
4265   ierr = MatInitializePackage();CHKERRQ(ierr);
4266   if (!next) {
4267     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4268     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4269     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4270     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4271     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4272     PetscFunctionReturn(0);
4273   }
4274   while (next) {
4275     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4276     if (flg) {
4277       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4278       inext = next->handlers;
4279       while (inext) {
4280         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4281         if (flg) {
4282           inext->getfactor[(int)ftype-1] = getfactor;
4283           PetscFunctionReturn(0);
4284         }
4285         iprev = inext;
4286         inext = inext->next;
4287       }
4288       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4289       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4290       iprev->next->getfactor[(int)ftype-1] = getfactor;
4291       PetscFunctionReturn(0);
4292     }
4293     prev = next;
4294     next = next->next;
4295   }
4296   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4297   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4298   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4299   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4300   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4301   PetscFunctionReturn(0);
4302 }
4303 
4304 /*@C
4305    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4306 
4307    Input Parameters:
4308 +    package - name of the package, for example petsc or superlu
4309 .    ftype - the type of factorization supported by the package
4310 -    mtype - the matrix type that works with this package
4311 
4312    Output Parameters:
4313 +   foundpackage - PETSC_TRUE if the package was registered
4314 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4315 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4316 
4317     Level: intermediate
4318 
4319 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4320 @*/
4321 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4322 {
4323   PetscErrorCode                 ierr;
4324   MatSolverTypeHolder         next = MatSolverTypeHolders;
4325   PetscBool                      flg;
4326   MatSolverTypeForSpecifcType inext;
4327 
4328   PetscFunctionBegin;
4329   if (foundpackage) *foundpackage = PETSC_FALSE;
4330   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4331   if (getfactor)    *getfactor    = NULL;
4332 
4333   if (package) {
4334     while (next) {
4335       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4336       if (flg) {
4337         if (foundpackage) *foundpackage = PETSC_TRUE;
4338         inext = next->handlers;
4339         while (inext) {
4340           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4341           if (flg) {
4342             if (foundmtype) *foundmtype = PETSC_TRUE;
4343             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4344             PetscFunctionReturn(0);
4345           }
4346           inext = inext->next;
4347         }
4348       }
4349       next = next->next;
4350     }
4351   } else {
4352     while (next) {
4353       inext = next->handlers;
4354       while (inext) {
4355         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4356         if (flg && inext->getfactor[(int)ftype-1]) {
4357           if (foundpackage) *foundpackage = PETSC_TRUE;
4358           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4359           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4360           PetscFunctionReturn(0);
4361         }
4362         inext = inext->next;
4363       }
4364       next = next->next;
4365     }
4366   }
4367   PetscFunctionReturn(0);
4368 }
4369 
4370 PetscErrorCode MatSolverTypeDestroy(void)
4371 {
4372   PetscErrorCode              ierr;
4373   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4374   MatSolverTypeForSpecifcType inext,iprev;
4375 
4376   PetscFunctionBegin;
4377   while (next) {
4378     ierr = PetscFree(next->name);CHKERRQ(ierr);
4379     inext = next->handlers;
4380     while (inext) {
4381       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4382       iprev = inext;
4383       inext = inext->next;
4384       ierr = PetscFree(iprev);CHKERRQ(ierr);
4385     }
4386     prev = next;
4387     next = next->next;
4388     ierr = PetscFree(prev);CHKERRQ(ierr);
4389   }
4390   MatSolverTypeHolders = NULL;
4391   PetscFunctionReturn(0);
4392 }
4393 
4394 /*@C
4395    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4396 
4397    Collective on Mat
4398 
4399    Input Parameters:
4400 +  mat - the matrix
4401 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4402 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4403 
4404    Output Parameters:
4405 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4406 
4407    Notes:
4408       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4409      such as pastix, superlu, mumps etc.
4410 
4411       PETSc must have been ./configure to use the external solver, using the option --download-package
4412 
4413    Level: intermediate
4414 
4415 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4416 @*/
4417 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4418 {
4419   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4420   PetscBool      foundpackage,foundmtype;
4421 
4422   PetscFunctionBegin;
4423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4424   PetscValidType(mat,1);
4425 
4426   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4427   MatCheckPreallocated(mat,1);
4428 
4429   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4430   if (!foundpackage) {
4431     if (type) {
4432       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4433     } else {
4434       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4435     }
4436   }
4437 
4438   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4439   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4440 
4441 #if defined(PETSC_USE_COMPLEX)
4442   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4443 #endif
4444 
4445   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4446   PetscFunctionReturn(0);
4447 }
4448 
4449 /*@C
4450    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4451 
4452    Not Collective
4453 
4454    Input Parameters:
4455 +  mat - the matrix
4456 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4457 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4458 
4459    Output Parameter:
4460 .    flg - PETSC_TRUE if the factorization is available
4461 
4462    Notes:
4463       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4464      such as pastix, superlu, mumps etc.
4465 
4466       PETSc must have been ./configure to use the external solver, using the option --download-package
4467 
4468    Level: intermediate
4469 
4470 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4471 @*/
4472 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4473 {
4474   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4475 
4476   PetscFunctionBegin;
4477   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4478   PetscValidType(mat,1);
4479 
4480   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4481   MatCheckPreallocated(mat,1);
4482 
4483   *flg = PETSC_FALSE;
4484   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4485   if (gconv) {
4486     *flg = PETSC_TRUE;
4487   }
4488   PetscFunctionReturn(0);
4489 }
4490 
4491 #include <petscdmtypes.h>
4492 
4493 /*@
4494    MatDuplicate - Duplicates a matrix including the non-zero structure.
4495 
4496    Collective on Mat
4497 
4498    Input Parameters:
4499 +  mat - the matrix
4500 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4501         See the manual page for MatDuplicateOption for an explanation of these options.
4502 
4503    Output Parameter:
4504 .  M - pointer to place new matrix
4505 
4506    Level: intermediate
4507 
4508    Notes:
4509     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4510     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.
4511 
4512 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4513 @*/
4514 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4515 {
4516   PetscErrorCode ierr;
4517   Mat            B;
4518   PetscInt       i;
4519   DM             dm;
4520   void           (*viewf)(void);
4521 
4522   PetscFunctionBegin;
4523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4524   PetscValidType(mat,1);
4525   PetscValidPointer(M,3);
4526   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4527   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4528   MatCheckPreallocated(mat,1);
4529 
4530   *M = 0;
4531   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4532   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4533   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4534   B    = *M;
4535 
4536   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4537   if (viewf) {
4538     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4539   }
4540 
4541   B->stencil.dim = mat->stencil.dim;
4542   B->stencil.noc = mat->stencil.noc;
4543   for (i=0; i<=mat->stencil.dim; i++) {
4544     B->stencil.dims[i]   = mat->stencil.dims[i];
4545     B->stencil.starts[i] = mat->stencil.starts[i];
4546   }
4547 
4548   B->nooffproczerorows = mat->nooffproczerorows;
4549   B->nooffprocentries  = mat->nooffprocentries;
4550 
4551   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4552   if (dm) {
4553     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4554   }
4555   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4556   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4557   PetscFunctionReturn(0);
4558 }
4559 
4560 /*@
4561    MatGetDiagonal - Gets the diagonal of a matrix.
4562 
4563    Logically Collective on Mat
4564 
4565    Input Parameters:
4566 +  mat - the matrix
4567 -  v - the vector for storing the diagonal
4568 
4569    Output Parameter:
4570 .  v - the diagonal of the matrix
4571 
4572    Level: intermediate
4573 
4574    Note:
4575    Currently only correct in parallel for square matrices.
4576 
4577 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4578 @*/
4579 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4580 {
4581   PetscErrorCode ierr;
4582 
4583   PetscFunctionBegin;
4584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4585   PetscValidType(mat,1);
4586   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4587   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4588   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4589   MatCheckPreallocated(mat,1);
4590 
4591   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4592   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4593   PetscFunctionReturn(0);
4594 }
4595 
4596 /*@C
4597    MatGetRowMin - Gets the minimum value (of the real part) of each
4598         row of the matrix
4599 
4600    Logically Collective on Mat
4601 
4602    Input Parameters:
4603 .  mat - the matrix
4604 
4605    Output Parameter:
4606 +  v - the vector for storing the maximums
4607 -  idx - the indices of the column found for each row (optional)
4608 
4609    Level: intermediate
4610 
4611    Notes:
4612     The result of this call are the same as if one converted the matrix to dense format
4613       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4614 
4615     This code is only implemented for a couple of matrix formats.
4616 
4617 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4618           MatGetRowMax()
4619 @*/
4620 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4621 {
4622   PetscErrorCode ierr;
4623 
4624   PetscFunctionBegin;
4625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4626   PetscValidType(mat,1);
4627   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4628   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4629   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4630   MatCheckPreallocated(mat,1);
4631 
4632   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4633   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4634   PetscFunctionReturn(0);
4635 }
4636 
4637 /*@C
4638    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4639         row of the matrix
4640 
4641    Logically Collective on Mat
4642 
4643    Input Parameters:
4644 .  mat - the matrix
4645 
4646    Output Parameter:
4647 +  v - the vector for storing the minimums
4648 -  idx - the indices of the column found for each row (or NULL if not needed)
4649 
4650    Level: intermediate
4651 
4652    Notes:
4653     if a row is completely empty or has only 0.0 values then the idx[] value for that
4654     row is 0 (the first column).
4655 
4656     This code is only implemented for a couple of matrix formats.
4657 
4658 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4659 @*/
4660 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4661 {
4662   PetscErrorCode ierr;
4663 
4664   PetscFunctionBegin;
4665   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4666   PetscValidType(mat,1);
4667   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4668   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4669   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4670   MatCheckPreallocated(mat,1);
4671   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4672 
4673   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4674   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4675   PetscFunctionReturn(0);
4676 }
4677 
4678 /*@C
4679    MatGetRowMax - Gets the maximum value (of the real part) of each
4680         row of the matrix
4681 
4682    Logically Collective on Mat
4683 
4684    Input Parameters:
4685 .  mat - the matrix
4686 
4687    Output Parameter:
4688 +  v - the vector for storing the maximums
4689 -  idx - the indices of the column found for each row (optional)
4690 
4691    Level: intermediate
4692 
4693    Notes:
4694     The result of this call are the same as if one converted the matrix to dense format
4695       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4696 
4697     This code is only implemented for a couple of matrix formats.
4698 
4699 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4700 @*/
4701 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4702 {
4703   PetscErrorCode ierr;
4704 
4705   PetscFunctionBegin;
4706   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4707   PetscValidType(mat,1);
4708   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4709   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4710   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4711   MatCheckPreallocated(mat,1);
4712 
4713   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4714   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4715   PetscFunctionReturn(0);
4716 }
4717 
4718 /*@C
4719    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4720         row of the matrix
4721 
4722    Logically Collective on Mat
4723 
4724    Input Parameters:
4725 .  mat - the matrix
4726 
4727    Output Parameter:
4728 +  v - the vector for storing the maximums
4729 -  idx - the indices of the column found for each row (or NULL if not needed)
4730 
4731    Level: intermediate
4732 
4733    Notes:
4734     if a row is completely empty or has only 0.0 values then the idx[] value for that
4735     row is 0 (the first column).
4736 
4737     This code is only implemented for a couple of matrix formats.
4738 
4739 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4740 @*/
4741 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4742 {
4743   PetscErrorCode ierr;
4744 
4745   PetscFunctionBegin;
4746   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4747   PetscValidType(mat,1);
4748   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4749   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4750   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4751   MatCheckPreallocated(mat,1);
4752   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4753 
4754   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4755   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4756   PetscFunctionReturn(0);
4757 }
4758 
4759 /*@
4760    MatGetRowSum - Gets the sum of each row of the matrix
4761 
4762    Logically or Neighborhood Collective on Mat
4763 
4764    Input Parameters:
4765 .  mat - the matrix
4766 
4767    Output Parameter:
4768 .  v - the vector for storing the sum of rows
4769 
4770    Level: intermediate
4771 
4772    Notes:
4773     This code is slow since it is not currently specialized for different formats
4774 
4775 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4776 @*/
4777 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4778 {
4779   Vec            ones;
4780   PetscErrorCode ierr;
4781 
4782   PetscFunctionBegin;
4783   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4784   PetscValidType(mat,1);
4785   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4786   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4787   MatCheckPreallocated(mat,1);
4788   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4789   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4790   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4791   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4792   PetscFunctionReturn(0);
4793 }
4794 
4795 /*@
4796    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4797 
4798    Collective on Mat
4799 
4800    Input Parameter:
4801 +  mat - the matrix to transpose
4802 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4803 
4804    Output Parameters:
4805 .  B - the transpose
4806 
4807    Notes:
4808      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4809 
4810      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4811 
4812      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4813 
4814    Level: intermediate
4815 
4816 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4817 @*/
4818 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4819 {
4820   PetscErrorCode ierr;
4821 
4822   PetscFunctionBegin;
4823   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4824   PetscValidType(mat,1);
4825   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4826   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4827   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4828   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4829   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4830   MatCheckPreallocated(mat,1);
4831 
4832   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4833   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4834   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4835   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4836   PetscFunctionReturn(0);
4837 }
4838 
4839 /*@
4840    MatIsTranspose - Test whether a matrix is another one's transpose,
4841         or its own, in which case it tests symmetry.
4842 
4843    Collective on Mat
4844 
4845    Input Parameter:
4846 +  A - the matrix to test
4847 -  B - the matrix to test against, this can equal the first parameter
4848 
4849    Output Parameters:
4850 .  flg - the result
4851 
4852    Notes:
4853    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4854    has a running time of the order of the number of nonzeros; the parallel
4855    test involves parallel copies of the block-offdiagonal parts of the matrix.
4856 
4857    Level: intermediate
4858 
4859 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4860 @*/
4861 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4862 {
4863   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4864 
4865   PetscFunctionBegin;
4866   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4867   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4868   PetscValidBoolPointer(flg,3);
4869   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4870   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4871   *flg = PETSC_FALSE;
4872   if (f && g) {
4873     if (f == g) {
4874       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4875     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4876   } else {
4877     MatType mattype;
4878     if (!f) {
4879       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4880     } else {
4881       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4882     }
4883     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4884   }
4885   PetscFunctionReturn(0);
4886 }
4887 
4888 /*@
4889    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4890 
4891    Collective on Mat
4892 
4893    Input Parameter:
4894 +  mat - the matrix to transpose and complex conjugate
4895 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4896 
4897    Output Parameters:
4898 .  B - the Hermitian
4899 
4900    Level: intermediate
4901 
4902 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4903 @*/
4904 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4905 {
4906   PetscErrorCode ierr;
4907 
4908   PetscFunctionBegin;
4909   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4910 #if defined(PETSC_USE_COMPLEX)
4911   ierr = MatConjugate(*B);CHKERRQ(ierr);
4912 #endif
4913   PetscFunctionReturn(0);
4914 }
4915 
4916 /*@
4917    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4918 
4919    Collective on Mat
4920 
4921    Input Parameter:
4922 +  A - the matrix to test
4923 -  B - the matrix to test against, this can equal the first parameter
4924 
4925    Output Parameters:
4926 .  flg - the result
4927 
4928    Notes:
4929    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4930    has a running time of the order of the number of nonzeros; the parallel
4931    test involves parallel copies of the block-offdiagonal parts of the matrix.
4932 
4933    Level: intermediate
4934 
4935 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4936 @*/
4937 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4938 {
4939   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4940 
4941   PetscFunctionBegin;
4942   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4943   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4944   PetscValidBoolPointer(flg,3);
4945   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4946   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4947   if (f && g) {
4948     if (f==g) {
4949       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4950     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4951   }
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 /*@
4956    MatPermute - Creates a new matrix with rows and columns permuted from the
4957    original.
4958 
4959    Collective on Mat
4960 
4961    Input Parameters:
4962 +  mat - the matrix to permute
4963 .  row - row permutation, each processor supplies only the permutation for its rows
4964 -  col - column permutation, each processor supplies only the permutation for its columns
4965 
4966    Output Parameters:
4967 .  B - the permuted matrix
4968 
4969    Level: advanced
4970 
4971    Note:
4972    The index sets map from row/col of permuted matrix to row/col of original matrix.
4973    The index sets should be on the same communicator as Mat and have the same local sizes.
4974 
4975 .seealso: MatGetOrdering(), ISAllGather()
4976 
4977 @*/
4978 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4979 {
4980   PetscErrorCode ierr;
4981 
4982   PetscFunctionBegin;
4983   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4984   PetscValidType(mat,1);
4985   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4986   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4987   PetscValidPointer(B,4);
4988   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4989   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4990   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4991   MatCheckPreallocated(mat,1);
4992 
4993   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4994   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4995   PetscFunctionReturn(0);
4996 }
4997 
4998 /*@
4999    MatEqual - Compares two matrices.
5000 
5001    Collective on Mat
5002 
5003    Input Parameters:
5004 +  A - the first matrix
5005 -  B - the second matrix
5006 
5007    Output Parameter:
5008 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5009 
5010    Level: intermediate
5011 
5012 @*/
5013 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5014 {
5015   PetscErrorCode ierr;
5016 
5017   PetscFunctionBegin;
5018   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5019   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5020   PetscValidType(A,1);
5021   PetscValidType(B,2);
5022   PetscValidBoolPointer(flg,3);
5023   PetscCheckSameComm(A,1,B,2);
5024   MatCheckPreallocated(B,2);
5025   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5026   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5027   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
5028   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5029   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5030   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
5031   MatCheckPreallocated(A,1);
5032 
5033   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 /*@
5038    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5039    matrices that are stored as vectors.  Either of the two scaling
5040    matrices can be NULL.
5041 
5042    Collective on Mat
5043 
5044    Input Parameters:
5045 +  mat - the matrix to be scaled
5046 .  l - the left scaling vector (or NULL)
5047 -  r - the right scaling vector (or NULL)
5048 
5049    Notes:
5050    MatDiagonalScale() computes A = LAR, where
5051    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5052    The L scales the rows of the matrix, the R scales the columns of the matrix.
5053 
5054    Level: intermediate
5055 
5056 
5057 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5058 @*/
5059 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5060 {
5061   PetscErrorCode ierr;
5062 
5063   PetscFunctionBegin;
5064   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5065   PetscValidType(mat,1);
5066   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5067   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5068   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5069   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5070   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5071   MatCheckPreallocated(mat,1);
5072 
5073   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5074   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5075   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5076   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5077 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5078   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5079     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5080   }
5081 #endif
5082   PetscFunctionReturn(0);
5083 }
5084 
5085 /*@
5086     MatScale - Scales all elements of a matrix by a given number.
5087 
5088     Logically Collective on Mat
5089 
5090     Input Parameters:
5091 +   mat - the matrix to be scaled
5092 -   a  - the scaling value
5093 
5094     Output Parameter:
5095 .   mat - the scaled matrix
5096 
5097     Level: intermediate
5098 
5099 .seealso: MatDiagonalScale()
5100 @*/
5101 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5102 {
5103   PetscErrorCode ierr;
5104 
5105   PetscFunctionBegin;
5106   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5107   PetscValidType(mat,1);
5108   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5109   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5110   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5111   PetscValidLogicalCollectiveScalar(mat,a,2);
5112   MatCheckPreallocated(mat,1);
5113 
5114   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5115   if (a != (PetscScalar)1.0) {
5116     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5117     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5118 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5119     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5120       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5121     }
5122 #endif
5123   }
5124   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5125   PetscFunctionReturn(0);
5126 }
5127 
5128 /*@
5129    MatNorm - Calculates various norms of a matrix.
5130 
5131    Collective on Mat
5132 
5133    Input Parameters:
5134 +  mat - the matrix
5135 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5136 
5137    Output Parameters:
5138 .  nrm - the resulting norm
5139 
5140    Level: intermediate
5141 
5142 @*/
5143 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5144 {
5145   PetscErrorCode ierr;
5146 
5147   PetscFunctionBegin;
5148   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5149   PetscValidType(mat,1);
5150   PetscValidScalarPointer(nrm,3);
5151 
5152   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5153   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5154   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5155   MatCheckPreallocated(mat,1);
5156 
5157   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5158   PetscFunctionReturn(0);
5159 }
5160 
5161 /*
5162      This variable is used to prevent counting of MatAssemblyBegin() that
5163    are called from within a MatAssemblyEnd().
5164 */
5165 static PetscInt MatAssemblyEnd_InUse = 0;
5166 /*@
5167    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5168    be called after completing all calls to MatSetValues().
5169 
5170    Collective on Mat
5171 
5172    Input Parameters:
5173 +  mat - the matrix
5174 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5175 
5176    Notes:
5177    MatSetValues() generally caches the values.  The matrix is ready to
5178    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5179    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5180    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5181    using the matrix.
5182 
5183    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5184    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
5185    a global collective operation requring all processes that share the matrix.
5186 
5187    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5188    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5189    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5190 
5191    Level: beginner
5192 
5193 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5194 @*/
5195 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5196 {
5197   PetscErrorCode ierr;
5198 
5199   PetscFunctionBegin;
5200   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5201   PetscValidType(mat,1);
5202   MatCheckPreallocated(mat,1);
5203   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5204   if (mat->assembled) {
5205     mat->was_assembled = PETSC_TRUE;
5206     mat->assembled     = PETSC_FALSE;
5207   }
5208 
5209   if (!MatAssemblyEnd_InUse) {
5210     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5211     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5212     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5213   } else if (mat->ops->assemblybegin) {
5214     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5215   }
5216   PetscFunctionReturn(0);
5217 }
5218 
5219 /*@
5220    MatAssembled - Indicates if a matrix has been assembled and is ready for
5221      use; for example, in matrix-vector product.
5222 
5223    Not Collective
5224 
5225    Input Parameter:
5226 .  mat - the matrix
5227 
5228    Output Parameter:
5229 .  assembled - PETSC_TRUE or PETSC_FALSE
5230 
5231    Level: advanced
5232 
5233 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5234 @*/
5235 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5236 {
5237   PetscFunctionBegin;
5238   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5239   PetscValidPointer(assembled,2);
5240   *assembled = mat->assembled;
5241   PetscFunctionReturn(0);
5242 }
5243 
5244 /*@
5245    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5246    be called after MatAssemblyBegin().
5247 
5248    Collective on Mat
5249 
5250    Input Parameters:
5251 +  mat - the matrix
5252 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5253 
5254    Options Database Keys:
5255 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5256 .  -mat_view ::ascii_info_detail - Prints more detailed info
5257 .  -mat_view - Prints matrix in ASCII format
5258 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5259 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5260 .  -display <name> - Sets display name (default is host)
5261 .  -draw_pause <sec> - Sets number of seconds to pause after display
5262 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5263 .  -viewer_socket_machine <machine> - Machine to use for socket
5264 .  -viewer_socket_port <port> - Port number to use for socket
5265 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5266 
5267    Notes:
5268    MatSetValues() generally caches the values.  The matrix is ready to
5269    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5270    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5271    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5272    using the matrix.
5273 
5274    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5275    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5276    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5277 
5278    Level: beginner
5279 
5280 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5281 @*/
5282 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5283 {
5284   PetscErrorCode  ierr;
5285   static PetscInt inassm = 0;
5286   PetscBool       flg    = PETSC_FALSE;
5287 
5288   PetscFunctionBegin;
5289   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5290   PetscValidType(mat,1);
5291 
5292   inassm++;
5293   MatAssemblyEnd_InUse++;
5294   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5295     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5296     if (mat->ops->assemblyend) {
5297       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5298     }
5299     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5300   } else if (mat->ops->assemblyend) {
5301     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5302   }
5303 
5304   /* Flush assembly is not a true assembly */
5305   if (type != MAT_FLUSH_ASSEMBLY) {
5306     mat->assembled        = PETSC_TRUE;
5307     mat->num_ass++;
5308     mat->ass_nonzerostate = mat->nonzerostate;
5309   }
5310 
5311   mat->insertmode = NOT_SET_VALUES;
5312   MatAssemblyEnd_InUse--;
5313   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5314   if (!mat->symmetric_eternal) {
5315     mat->symmetric_set              = PETSC_FALSE;
5316     mat->hermitian_set              = PETSC_FALSE;
5317     mat->structurally_symmetric_set = PETSC_FALSE;
5318   }
5319 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5320   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5321     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5322   }
5323 #endif
5324   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5325     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5326 
5327     if (mat->checksymmetryonassembly) {
5328       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5329       if (flg) {
5330         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5331       } else {
5332         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5333       }
5334     }
5335     if (mat->nullsp && mat->checknullspaceonassembly) {
5336       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5337     }
5338   }
5339   inassm--;
5340   PetscFunctionReturn(0);
5341 }
5342 
5343 /*@
5344    MatSetOption - Sets a parameter option for a matrix. Some options
5345    may be specific to certain storage formats.  Some options
5346    determine how values will be inserted (or added). Sorted,
5347    row-oriented input will generally assemble the fastest. The default
5348    is row-oriented.
5349 
5350    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5351 
5352    Input Parameters:
5353 +  mat - the matrix
5354 .  option - the option, one of those listed below (and possibly others),
5355 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5356 
5357   Options Describing Matrix Structure:
5358 +    MAT_SPD - symmetric positive definite
5359 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5360 .    MAT_HERMITIAN - transpose is the complex conjugation
5361 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5362 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5363                             you set to be kept with all future use of the matrix
5364                             including after MatAssemblyBegin/End() which could
5365                             potentially change the symmetry structure, i.e. you
5366                             KNOW the matrix will ALWAYS have the property you set.
5367 
5368 
5369    Options For Use with MatSetValues():
5370    Insert a logically dense subblock, which can be
5371 .    MAT_ROW_ORIENTED - row-oriented (default)
5372 
5373    Note these options reflect the data you pass in with MatSetValues(); it has
5374    nothing to do with how the data is stored internally in the matrix
5375    data structure.
5376 
5377    When (re)assembling a matrix, we can restrict the input for
5378    efficiency/debugging purposes.  These options include:
5379 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5380 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5381 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5382 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5383 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5384 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5385         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5386         performance for very large process counts.
5387 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5388         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5389         functions, instead sending only neighbor messages.
5390 
5391    Notes:
5392    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5393 
5394    Some options are relevant only for particular matrix types and
5395    are thus ignored by others.  Other options are not supported by
5396    certain matrix types and will generate an error message if set.
5397 
5398    If using a Fortran 77 module to compute a matrix, one may need to
5399    use the column-oriented option (or convert to the row-oriented
5400    format).
5401 
5402    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5403    that would generate a new entry in the nonzero structure is instead
5404    ignored.  Thus, if memory has not alredy been allocated for this particular
5405    data, then the insertion is ignored. For dense matrices, in which
5406    the entire array is allocated, no entries are ever ignored.
5407    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5408 
5409    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5410    that would generate a new entry in the nonzero structure instead produces
5411    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
5412 
5413    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5414    that would generate a new entry that has not been preallocated will
5415    instead produce an error. (Currently supported for AIJ and BAIJ formats
5416    only.) This is a useful flag when debugging matrix memory preallocation.
5417    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5418 
5419    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5420    other processors should be dropped, rather than stashed.
5421    This is useful if you know that the "owning" processor is also
5422    always generating the correct matrix entries, so that PETSc need
5423    not transfer duplicate entries generated on another processor.
5424 
5425    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5426    searches during matrix assembly. When this flag is set, the hash table
5427    is created during the first Matrix Assembly. This hash table is
5428    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5429    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5430    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5431    supported by MATMPIBAIJ format only.
5432 
5433    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5434    are kept in the nonzero structure
5435 
5436    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5437    a zero location in the matrix
5438 
5439    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5440 
5441    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5442         zero row routines and thus improves performance for very large process counts.
5443 
5444    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5445         part of the matrix (since they should match the upper triangular part).
5446 
5447    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5448                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5449                      with finite difference schemes with non-periodic boundary conditions.
5450    Notes:
5451     Can only be called after MatSetSizes() and MatSetType() have been set.
5452 
5453    Level: intermediate
5454 
5455 .seealso:  MatOption, Mat
5456 
5457 @*/
5458 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5459 {
5460   PetscErrorCode ierr;
5461 
5462   PetscFunctionBegin;
5463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5464   PetscValidType(mat,1);
5465   if (op > 0) {
5466     PetscValidLogicalCollectiveEnum(mat,op,2);
5467     PetscValidLogicalCollectiveBool(mat,flg,3);
5468   }
5469 
5470   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5471   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5472 
5473   switch (op) {
5474   case MAT_NO_OFF_PROC_ENTRIES:
5475     mat->nooffprocentries = flg;
5476     PetscFunctionReturn(0);
5477     break;
5478   case MAT_SUBSET_OFF_PROC_ENTRIES:
5479     mat->assembly_subset = flg;
5480     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5481 #if !defined(PETSC_HAVE_MPIUNI)
5482       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5483 #endif
5484       mat->stash.first_assembly_done = PETSC_FALSE;
5485     }
5486     PetscFunctionReturn(0);
5487   case MAT_NO_OFF_PROC_ZERO_ROWS:
5488     mat->nooffproczerorows = flg;
5489     PetscFunctionReturn(0);
5490     break;
5491   case MAT_SPD:
5492     mat->spd_set = PETSC_TRUE;
5493     mat->spd     = flg;
5494     if (flg) {
5495       mat->symmetric                  = PETSC_TRUE;
5496       mat->structurally_symmetric     = PETSC_TRUE;
5497       mat->symmetric_set              = PETSC_TRUE;
5498       mat->structurally_symmetric_set = PETSC_TRUE;
5499     }
5500     break;
5501   case MAT_SYMMETRIC:
5502     mat->symmetric = flg;
5503     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5504     mat->symmetric_set              = PETSC_TRUE;
5505     mat->structurally_symmetric_set = flg;
5506 #if !defined(PETSC_USE_COMPLEX)
5507     mat->hermitian     = flg;
5508     mat->hermitian_set = PETSC_TRUE;
5509 #endif
5510     break;
5511   case MAT_HERMITIAN:
5512     mat->hermitian = flg;
5513     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5514     mat->hermitian_set              = PETSC_TRUE;
5515     mat->structurally_symmetric_set = flg;
5516 #if !defined(PETSC_USE_COMPLEX)
5517     mat->symmetric     = flg;
5518     mat->symmetric_set = PETSC_TRUE;
5519 #endif
5520     break;
5521   case MAT_STRUCTURALLY_SYMMETRIC:
5522     mat->structurally_symmetric     = flg;
5523     mat->structurally_symmetric_set = PETSC_TRUE;
5524     break;
5525   case MAT_SYMMETRY_ETERNAL:
5526     mat->symmetric_eternal = flg;
5527     break;
5528   case MAT_STRUCTURE_ONLY:
5529     mat->structure_only = flg;
5530     break;
5531   case MAT_SORTED_FULL:
5532     mat->sortedfull = flg;
5533     break;
5534   default:
5535     break;
5536   }
5537   if (mat->ops->setoption) {
5538     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5539   }
5540   PetscFunctionReturn(0);
5541 }
5542 
5543 /*@
5544    MatGetOption - Gets a parameter option that has been set for a matrix.
5545 
5546    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5547 
5548    Input Parameters:
5549 +  mat - the matrix
5550 -  option - the option, this only responds to certain options, check the code for which ones
5551 
5552    Output Parameter:
5553 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5554 
5555     Notes:
5556     Can only be called after MatSetSizes() and MatSetType() have been set.
5557 
5558    Level: intermediate
5559 
5560 .seealso:  MatOption, MatSetOption()
5561 
5562 @*/
5563 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5564 {
5565   PetscFunctionBegin;
5566   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5567   PetscValidType(mat,1);
5568 
5569   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5570   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5571 
5572   switch (op) {
5573   case MAT_NO_OFF_PROC_ENTRIES:
5574     *flg = mat->nooffprocentries;
5575     break;
5576   case MAT_NO_OFF_PROC_ZERO_ROWS:
5577     *flg = mat->nooffproczerorows;
5578     break;
5579   case MAT_SYMMETRIC:
5580     *flg = mat->symmetric;
5581     break;
5582   case MAT_HERMITIAN:
5583     *flg = mat->hermitian;
5584     break;
5585   case MAT_STRUCTURALLY_SYMMETRIC:
5586     *flg = mat->structurally_symmetric;
5587     break;
5588   case MAT_SYMMETRY_ETERNAL:
5589     *flg = mat->symmetric_eternal;
5590     break;
5591   case MAT_SPD:
5592     *flg = mat->spd;
5593     break;
5594   default:
5595     break;
5596   }
5597   PetscFunctionReturn(0);
5598 }
5599 
5600 /*@
5601    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5602    this routine retains the old nonzero structure.
5603 
5604    Logically Collective on Mat
5605 
5606    Input Parameters:
5607 .  mat - the matrix
5608 
5609    Level: intermediate
5610 
5611    Notes:
5612     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.
5613    See the Performance chapter of the users manual for information on preallocating matrices.
5614 
5615 .seealso: MatZeroRows()
5616 @*/
5617 PetscErrorCode MatZeroEntries(Mat mat)
5618 {
5619   PetscErrorCode ierr;
5620 
5621   PetscFunctionBegin;
5622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5623   PetscValidType(mat,1);
5624   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5625   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5626   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5627   MatCheckPreallocated(mat,1);
5628 
5629   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5630   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5631   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5632   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5633 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5634   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5635     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5636   }
5637 #endif
5638   PetscFunctionReturn(0);
5639 }
5640 
5641 /*@
5642    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5643    of a set of rows and columns of a matrix.
5644 
5645    Collective on Mat
5646 
5647    Input Parameters:
5648 +  mat - the matrix
5649 .  numRows - the number of rows to remove
5650 .  rows - the global row indices
5651 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5652 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5653 -  b - optional vector of right hand side, that will be adjusted by provided solution
5654 
5655    Notes:
5656    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5657 
5658    The user can set a value in the diagonal entry (or for the AIJ and
5659    row formats can optionally remove the main diagonal entry from the
5660    nonzero structure as well, by passing 0.0 as the final argument).
5661 
5662    For the parallel case, all processes that share the matrix (i.e.,
5663    those in the communicator used for matrix creation) MUST call this
5664    routine, regardless of whether any rows being zeroed are owned by
5665    them.
5666 
5667    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5668    list only rows local to itself).
5669 
5670    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5671 
5672    Level: intermediate
5673 
5674 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5675           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5676 @*/
5677 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5678 {
5679   PetscErrorCode ierr;
5680 
5681   PetscFunctionBegin;
5682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5683   PetscValidType(mat,1);
5684   if (numRows) PetscValidIntPointer(rows,3);
5685   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5686   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5687   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5688   MatCheckPreallocated(mat,1);
5689 
5690   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5691   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5692   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5693 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5694   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5695     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5696   }
5697 #endif
5698   PetscFunctionReturn(0);
5699 }
5700 
5701 /*@
5702    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5703    of a set of rows and columns of a matrix.
5704 
5705    Collective on Mat
5706 
5707    Input Parameters:
5708 +  mat - the matrix
5709 .  is - the rows to zero
5710 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5711 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5712 -  b - optional vector of right hand side, that will be adjusted by provided solution
5713 
5714    Notes:
5715    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5716 
5717    The user can set a value in the diagonal entry (or for the AIJ and
5718    row formats can optionally remove the main diagonal entry from the
5719    nonzero structure as well, by passing 0.0 as the final argument).
5720 
5721    For the parallel case, all processes that share the matrix (i.e.,
5722    those in the communicator used for matrix creation) MUST call this
5723    routine, regardless of whether any rows being zeroed are owned by
5724    them.
5725 
5726    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5727    list only rows local to itself).
5728 
5729    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5730 
5731    Level: intermediate
5732 
5733 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5734           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5735 @*/
5736 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5737 {
5738   PetscErrorCode ierr;
5739   PetscInt       numRows;
5740   const PetscInt *rows;
5741 
5742   PetscFunctionBegin;
5743   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5744   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5745   PetscValidType(mat,1);
5746   PetscValidType(is,2);
5747   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5748   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5749   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5750   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5751   PetscFunctionReturn(0);
5752 }
5753 
5754 /*@
5755    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5756    of a set of rows of a matrix.
5757 
5758    Collective on Mat
5759 
5760    Input Parameters:
5761 +  mat - the matrix
5762 .  numRows - the number of rows to remove
5763 .  rows - the global row indices
5764 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5765 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5766 -  b - optional vector of right hand side, that will be adjusted by provided solution
5767 
5768    Notes:
5769    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5770    but does not release memory.  For the dense and block diagonal
5771    formats this does not alter the nonzero structure.
5772 
5773    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5774    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5775    merely zeroed.
5776 
5777    The user can set a value in the diagonal entry (or for the AIJ and
5778    row formats can optionally remove the main diagonal entry from the
5779    nonzero structure as well, by passing 0.0 as the final argument).
5780 
5781    For the parallel case, all processes that share the matrix (i.e.,
5782    those in the communicator used for matrix creation) MUST call this
5783    routine, regardless of whether any rows being zeroed are owned by
5784    them.
5785 
5786    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5787    list only rows local to itself).
5788 
5789    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5790    owns that are to be zeroed. This saves a global synchronization in the implementation.
5791 
5792    Level: intermediate
5793 
5794 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5795           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5796 @*/
5797 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5798 {
5799   PetscErrorCode ierr;
5800 
5801   PetscFunctionBegin;
5802   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5803   PetscValidType(mat,1);
5804   if (numRows) PetscValidIntPointer(rows,3);
5805   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5806   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5807   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5808   MatCheckPreallocated(mat,1);
5809 
5810   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5811   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5812   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5813 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5814   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5815     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5816   }
5817 #endif
5818   PetscFunctionReturn(0);
5819 }
5820 
5821 /*@
5822    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5823    of a set of rows of a matrix.
5824 
5825    Collective on Mat
5826 
5827    Input Parameters:
5828 +  mat - the matrix
5829 .  is - index set of rows to remove
5830 .  diag - value put in all diagonals of eliminated rows
5831 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5832 -  b - optional vector of right hand side, that will be adjusted by provided solution
5833 
5834    Notes:
5835    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5836    but does not release memory.  For the dense and block diagonal
5837    formats this does not alter the nonzero structure.
5838 
5839    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5840    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5841    merely zeroed.
5842 
5843    The user can set a value in the diagonal entry (or for the AIJ and
5844    row formats can optionally remove the main diagonal entry from the
5845    nonzero structure as well, by passing 0.0 as the final argument).
5846 
5847    For the parallel case, all processes that share the matrix (i.e.,
5848    those in the communicator used for matrix creation) MUST call this
5849    routine, regardless of whether any rows being zeroed are owned by
5850    them.
5851 
5852    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5853    list only rows local to itself).
5854 
5855    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5856    owns that are to be zeroed. This saves a global synchronization in the implementation.
5857 
5858    Level: intermediate
5859 
5860 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5861           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5862 @*/
5863 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5864 {
5865   PetscInt       numRows;
5866   const PetscInt *rows;
5867   PetscErrorCode ierr;
5868 
5869   PetscFunctionBegin;
5870   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5871   PetscValidType(mat,1);
5872   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5873   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5874   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5875   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5876   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5877   PetscFunctionReturn(0);
5878 }
5879 
5880 /*@
5881    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5882    of a set of rows of a matrix. These rows must be local to the process.
5883 
5884    Collective on Mat
5885 
5886    Input Parameters:
5887 +  mat - the matrix
5888 .  numRows - the number of rows to remove
5889 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5890 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5891 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5892 -  b - optional vector of right hand side, that will be adjusted by provided solution
5893 
5894    Notes:
5895    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5896    but does not release memory.  For the dense and block diagonal
5897    formats this does not alter the nonzero structure.
5898 
5899    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5900    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5901    merely zeroed.
5902 
5903    The user can set a value in the diagonal entry (or for the AIJ and
5904    row formats can optionally remove the main diagonal entry from the
5905    nonzero structure as well, by passing 0.0 as the final argument).
5906 
5907    For the parallel case, all processes that share the matrix (i.e.,
5908    those in the communicator used for matrix creation) MUST call this
5909    routine, regardless of whether any rows being zeroed are owned by
5910    them.
5911 
5912    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5913    list only rows local to itself).
5914 
5915    The grid coordinates are across the entire grid, not just the local portion
5916 
5917    In Fortran idxm and idxn should be declared as
5918 $     MatStencil idxm(4,m)
5919    and the values inserted using
5920 $    idxm(MatStencil_i,1) = i
5921 $    idxm(MatStencil_j,1) = j
5922 $    idxm(MatStencil_k,1) = k
5923 $    idxm(MatStencil_c,1) = c
5924    etc
5925 
5926    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5927    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5928    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5929    DM_BOUNDARY_PERIODIC boundary type.
5930 
5931    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
5932    a single value per point) you can skip filling those indices.
5933 
5934    Level: intermediate
5935 
5936 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5937           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5938 @*/
5939 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5940 {
5941   PetscInt       dim     = mat->stencil.dim;
5942   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5943   PetscInt       *dims   = mat->stencil.dims+1;
5944   PetscInt       *starts = mat->stencil.starts;
5945   PetscInt       *dxm    = (PetscInt*) rows;
5946   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5947   PetscErrorCode ierr;
5948 
5949   PetscFunctionBegin;
5950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5951   PetscValidType(mat,1);
5952   if (numRows) PetscValidIntPointer(rows,3);
5953 
5954   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5955   for (i = 0; i < numRows; ++i) {
5956     /* Skip unused dimensions (they are ordered k, j, i, c) */
5957     for (j = 0; j < 3-sdim; ++j) dxm++;
5958     /* Local index in X dir */
5959     tmp = *dxm++ - starts[0];
5960     /* Loop over remaining dimensions */
5961     for (j = 0; j < dim-1; ++j) {
5962       /* If nonlocal, set index to be negative */
5963       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5964       /* Update local index */
5965       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5966     }
5967     /* Skip component slot if necessary */
5968     if (mat->stencil.noc) dxm++;
5969     /* Local row number */
5970     if (tmp >= 0) {
5971       jdxm[numNewRows++] = tmp;
5972     }
5973   }
5974   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5975   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5976   PetscFunctionReturn(0);
5977 }
5978 
5979 /*@
5980    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5981    of a set of rows and columns of a matrix.
5982 
5983    Collective on Mat
5984 
5985    Input Parameters:
5986 +  mat - the matrix
5987 .  numRows - the number of rows/columns to remove
5988 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5989 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5990 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5991 -  b - optional vector of right hand side, that will be adjusted by provided solution
5992 
5993    Notes:
5994    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5995    but does not release memory.  For the dense and block diagonal
5996    formats this does not alter the nonzero structure.
5997 
5998    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5999    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6000    merely zeroed.
6001 
6002    The user can set a value in the diagonal entry (or for the AIJ and
6003    row formats can optionally remove the main diagonal entry from the
6004    nonzero structure as well, by passing 0.0 as the final argument).
6005 
6006    For the parallel case, all processes that share the matrix (i.e.,
6007    those in the communicator used for matrix creation) MUST call this
6008    routine, regardless of whether any rows being zeroed are owned by
6009    them.
6010 
6011    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6012    list only rows local to itself, but the row/column numbers are given in local numbering).
6013 
6014    The grid coordinates are across the entire grid, not just the local portion
6015 
6016    In Fortran idxm and idxn should be declared as
6017 $     MatStencil idxm(4,m)
6018    and the values inserted using
6019 $    idxm(MatStencil_i,1) = i
6020 $    idxm(MatStencil_j,1) = j
6021 $    idxm(MatStencil_k,1) = k
6022 $    idxm(MatStencil_c,1) = c
6023    etc
6024 
6025    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6026    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6027    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6028    DM_BOUNDARY_PERIODIC boundary type.
6029 
6030    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
6031    a single value per point) you can skip filling those indices.
6032 
6033    Level: intermediate
6034 
6035 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6036           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6037 @*/
6038 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6039 {
6040   PetscInt       dim     = mat->stencil.dim;
6041   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6042   PetscInt       *dims   = mat->stencil.dims+1;
6043   PetscInt       *starts = mat->stencil.starts;
6044   PetscInt       *dxm    = (PetscInt*) rows;
6045   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6046   PetscErrorCode ierr;
6047 
6048   PetscFunctionBegin;
6049   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6050   PetscValidType(mat,1);
6051   if (numRows) PetscValidIntPointer(rows,3);
6052 
6053   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6054   for (i = 0; i < numRows; ++i) {
6055     /* Skip unused dimensions (they are ordered k, j, i, c) */
6056     for (j = 0; j < 3-sdim; ++j) dxm++;
6057     /* Local index in X dir */
6058     tmp = *dxm++ - starts[0];
6059     /* Loop over remaining dimensions */
6060     for (j = 0; j < dim-1; ++j) {
6061       /* If nonlocal, set index to be negative */
6062       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6063       /* Update local index */
6064       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6065     }
6066     /* Skip component slot if necessary */
6067     if (mat->stencil.noc) dxm++;
6068     /* Local row number */
6069     if (tmp >= 0) {
6070       jdxm[numNewRows++] = tmp;
6071     }
6072   }
6073   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6074   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6075   PetscFunctionReturn(0);
6076 }
6077 
6078 /*@C
6079    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6080    of a set of rows of a matrix; using local numbering of rows.
6081 
6082    Collective on Mat
6083 
6084    Input Parameters:
6085 +  mat - the matrix
6086 .  numRows - the number of rows to remove
6087 .  rows - the global row indices
6088 .  diag - value put in all diagonals of eliminated rows
6089 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6090 -  b - optional vector of right hand side, that will be adjusted by provided solution
6091 
6092    Notes:
6093    Before calling MatZeroRowsLocal(), the user must first set the
6094    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6095 
6096    For the AIJ matrix formats this removes the old nonzero structure,
6097    but does not release memory.  For the dense and block diagonal
6098    formats this does not alter the nonzero structure.
6099 
6100    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6101    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6102    merely zeroed.
6103 
6104    The user can set a value in the diagonal entry (or for the AIJ and
6105    row formats can optionally remove the main diagonal entry from the
6106    nonzero structure as well, by passing 0.0 as the final argument).
6107 
6108    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6109    owns that are to be zeroed. This saves a global synchronization in the implementation.
6110 
6111    Level: intermediate
6112 
6113 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6114           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6115 @*/
6116 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6117 {
6118   PetscErrorCode ierr;
6119 
6120   PetscFunctionBegin;
6121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6122   PetscValidType(mat,1);
6123   if (numRows) PetscValidIntPointer(rows,3);
6124   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6125   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6126   MatCheckPreallocated(mat,1);
6127 
6128   if (mat->ops->zerorowslocal) {
6129     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6130   } else {
6131     IS             is, newis;
6132     const PetscInt *newRows;
6133 
6134     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6135     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6136     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6137     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6138     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6139     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6140     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6141     ierr = ISDestroy(&is);CHKERRQ(ierr);
6142   }
6143   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6144 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6145   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6146     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6147   }
6148 #endif
6149   PetscFunctionReturn(0);
6150 }
6151 
6152 /*@
6153    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6154    of a set of rows of a matrix; using local numbering of rows.
6155 
6156    Collective on Mat
6157 
6158    Input Parameters:
6159 +  mat - the matrix
6160 .  is - index set of rows to remove
6161 .  diag - value put in all diagonals of eliminated rows
6162 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6163 -  b - optional vector of right hand side, that will be adjusted by provided solution
6164 
6165    Notes:
6166    Before calling MatZeroRowsLocalIS(), the user must first set the
6167    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6168 
6169    For the AIJ matrix formats this removes the old nonzero structure,
6170    but does not release memory.  For the dense and block diagonal
6171    formats this does not alter the nonzero structure.
6172 
6173    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6174    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6175    merely zeroed.
6176 
6177    The user can set a value in the diagonal entry (or for the AIJ and
6178    row formats can optionally remove the main diagonal entry from the
6179    nonzero structure as well, by passing 0.0 as the final argument).
6180 
6181    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6182    owns that are to be zeroed. This saves a global synchronization in the implementation.
6183 
6184    Level: intermediate
6185 
6186 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6187           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6188 @*/
6189 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6190 {
6191   PetscErrorCode ierr;
6192   PetscInt       numRows;
6193   const PetscInt *rows;
6194 
6195   PetscFunctionBegin;
6196   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6197   PetscValidType(mat,1);
6198   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6199   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6200   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6201   MatCheckPreallocated(mat,1);
6202 
6203   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6204   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6205   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6206   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6207   PetscFunctionReturn(0);
6208 }
6209 
6210 /*@
6211    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6212    of a set of rows and columns of a matrix; using local numbering of rows.
6213 
6214    Collective on Mat
6215 
6216    Input Parameters:
6217 +  mat - the matrix
6218 .  numRows - the number of rows to remove
6219 .  rows - the global row indices
6220 .  diag - value put in all diagonals of eliminated rows
6221 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6222 -  b - optional vector of right hand side, that will be adjusted by provided solution
6223 
6224    Notes:
6225    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6226    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6227 
6228    The user can set a value in the diagonal entry (or for the AIJ and
6229    row formats can optionally remove the main diagonal entry from the
6230    nonzero structure as well, by passing 0.0 as the final argument).
6231 
6232    Level: intermediate
6233 
6234 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6235           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6236 @*/
6237 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6238 {
6239   PetscErrorCode ierr;
6240   IS             is, newis;
6241   const PetscInt *newRows;
6242 
6243   PetscFunctionBegin;
6244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6245   PetscValidType(mat,1);
6246   if (numRows) PetscValidIntPointer(rows,3);
6247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6249   MatCheckPreallocated(mat,1);
6250 
6251   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6252   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6253   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6254   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6255   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6256   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6257   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6258   ierr = ISDestroy(&is);CHKERRQ(ierr);
6259   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6260 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6261   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6262     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6263   }
6264 #endif
6265   PetscFunctionReturn(0);
6266 }
6267 
6268 /*@
6269    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6270    of a set of rows and columns of a matrix; using local numbering of rows.
6271 
6272    Collective on Mat
6273 
6274    Input Parameters:
6275 +  mat - the matrix
6276 .  is - index set of rows to remove
6277 .  diag - value put in all diagonals of eliminated rows
6278 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6279 -  b - optional vector of right hand side, that will be adjusted by provided solution
6280 
6281    Notes:
6282    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6283    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6284 
6285    The user can set a value in the diagonal entry (or for the AIJ and
6286    row formats can optionally remove the main diagonal entry from the
6287    nonzero structure as well, by passing 0.0 as the final argument).
6288 
6289    Level: intermediate
6290 
6291 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6292           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6293 @*/
6294 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6295 {
6296   PetscErrorCode ierr;
6297   PetscInt       numRows;
6298   const PetscInt *rows;
6299 
6300   PetscFunctionBegin;
6301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6302   PetscValidType(mat,1);
6303   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6304   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6305   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6306   MatCheckPreallocated(mat,1);
6307 
6308   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6309   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6310   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6311   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6312   PetscFunctionReturn(0);
6313 }
6314 
6315 /*@C
6316    MatGetSize - Returns the numbers of rows and columns in a matrix.
6317 
6318    Not Collective
6319 
6320    Input Parameter:
6321 .  mat - the matrix
6322 
6323    Output Parameters:
6324 +  m - the number of global rows
6325 -  n - the number of global columns
6326 
6327    Note: both output parameters can be NULL on input.
6328 
6329    Level: beginner
6330 
6331 .seealso: MatGetLocalSize()
6332 @*/
6333 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6334 {
6335   PetscFunctionBegin;
6336   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6337   if (m) *m = mat->rmap->N;
6338   if (n) *n = mat->cmap->N;
6339   PetscFunctionReturn(0);
6340 }
6341 
6342 /*@C
6343    MatGetLocalSize - Returns the number of rows and columns in a matrix
6344    stored locally.  This information may be implementation dependent, so
6345    use with care.
6346 
6347    Not Collective
6348 
6349    Input Parameters:
6350 .  mat - the matrix
6351 
6352    Output Parameters:
6353 +  m - the number of local rows
6354 -  n - the number of local columns
6355 
6356    Note: both output parameters can be NULL on input.
6357 
6358    Level: beginner
6359 
6360 .seealso: MatGetSize()
6361 @*/
6362 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6363 {
6364   PetscFunctionBegin;
6365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6366   if (m) PetscValidIntPointer(m,2);
6367   if (n) PetscValidIntPointer(n,3);
6368   if (m) *m = mat->rmap->n;
6369   if (n) *n = mat->cmap->n;
6370   PetscFunctionReturn(0);
6371 }
6372 
6373 /*@C
6374    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6375    this processor. (The columns of the "diagonal block")
6376 
6377    Not Collective, unless matrix has not been allocated, then collective on Mat
6378 
6379    Input Parameters:
6380 .  mat - the matrix
6381 
6382    Output Parameters:
6383 +  m - the global index of the first local column
6384 -  n - one more than the global index of the last local column
6385 
6386    Notes:
6387     both output parameters can be NULL on input.
6388 
6389    Level: developer
6390 
6391 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6392 
6393 @*/
6394 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6395 {
6396   PetscFunctionBegin;
6397   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6398   PetscValidType(mat,1);
6399   if (m) PetscValidIntPointer(m,2);
6400   if (n) PetscValidIntPointer(n,3);
6401   MatCheckPreallocated(mat,1);
6402   if (m) *m = mat->cmap->rstart;
6403   if (n) *n = mat->cmap->rend;
6404   PetscFunctionReturn(0);
6405 }
6406 
6407 /*@C
6408    MatGetOwnershipRange - Returns the range of matrix rows owned by
6409    this processor, assuming that the matrix is laid out with the first
6410    n1 rows on the first processor, the next n2 rows on the second, etc.
6411    For certain parallel layouts this range may not be well defined.
6412 
6413    Not Collective
6414 
6415    Input Parameters:
6416 .  mat - the matrix
6417 
6418    Output Parameters:
6419 +  m - the global index of the first local row
6420 -  n - one more than the global index of the last local row
6421 
6422    Note: Both output parameters can be NULL on input.
6423 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6424 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6425 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6426 
6427    Level: beginner
6428 
6429 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6430 
6431 @*/
6432 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6433 {
6434   PetscFunctionBegin;
6435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6436   PetscValidType(mat,1);
6437   if (m) PetscValidIntPointer(m,2);
6438   if (n) PetscValidIntPointer(n,3);
6439   MatCheckPreallocated(mat,1);
6440   if (m) *m = mat->rmap->rstart;
6441   if (n) *n = mat->rmap->rend;
6442   PetscFunctionReturn(0);
6443 }
6444 
6445 /*@C
6446    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6447    each process
6448 
6449    Not Collective, unless matrix has not been allocated, then collective on Mat
6450 
6451    Input Parameters:
6452 .  mat - the matrix
6453 
6454    Output Parameters:
6455 .  ranges - start of each processors portion plus one more than the total length at the end
6456 
6457    Level: beginner
6458 
6459 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6460 
6461 @*/
6462 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6463 {
6464   PetscErrorCode ierr;
6465 
6466   PetscFunctionBegin;
6467   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6468   PetscValidType(mat,1);
6469   MatCheckPreallocated(mat,1);
6470   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6471   PetscFunctionReturn(0);
6472 }
6473 
6474 /*@C
6475    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6476    this processor. (The columns of the "diagonal blocks" for each process)
6477 
6478    Not Collective, unless matrix has not been allocated, then collective on Mat
6479 
6480    Input Parameters:
6481 .  mat - the matrix
6482 
6483    Output Parameters:
6484 .  ranges - start of each processors portion plus one more then the total length at the end
6485 
6486    Level: beginner
6487 
6488 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6489 
6490 @*/
6491 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6492 {
6493   PetscErrorCode ierr;
6494 
6495   PetscFunctionBegin;
6496   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6497   PetscValidType(mat,1);
6498   MatCheckPreallocated(mat,1);
6499   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6500   PetscFunctionReturn(0);
6501 }
6502 
6503 /*@C
6504    MatGetOwnershipIS - Get row and column ownership as index sets
6505 
6506    Not Collective
6507 
6508    Input Arguments:
6509 .  A - matrix of type Elemental
6510 
6511    Output Arguments:
6512 +  rows - rows in which this process owns elements
6513 -  cols - columns in which this process owns elements
6514 
6515    Level: intermediate
6516 
6517 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6518 @*/
6519 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6520 {
6521   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6522 
6523   PetscFunctionBegin;
6524   MatCheckPreallocated(A,1);
6525   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6526   if (f) {
6527     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6528   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6529     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6530     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6531   }
6532   PetscFunctionReturn(0);
6533 }
6534 
6535 /*@C
6536    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6537    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6538    to complete the factorization.
6539 
6540    Collective on Mat
6541 
6542    Input Parameters:
6543 +  mat - the matrix
6544 .  row - row permutation
6545 .  column - column permutation
6546 -  info - structure containing
6547 $      levels - number of levels of fill.
6548 $      expected fill - as ratio of original fill.
6549 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6550                 missing diagonal entries)
6551 
6552    Output Parameters:
6553 .  fact - new matrix that has been symbolically factored
6554 
6555    Notes:
6556     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6557 
6558    Most users should employ the simplified KSP interface for linear solvers
6559    instead of working directly with matrix algebra routines such as this.
6560    See, e.g., KSPCreate().
6561 
6562    Level: developer
6563 
6564 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6565           MatGetOrdering(), MatFactorInfo
6566 
6567     Note: this uses the definition of level of fill as in Y. Saad, 2003
6568 
6569     Developer Note: fortran interface is not autogenerated as the f90
6570     interface defintion cannot be generated correctly [due to MatFactorInfo]
6571 
6572    References:
6573      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6574 @*/
6575 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6576 {
6577   PetscErrorCode ierr;
6578 
6579   PetscFunctionBegin;
6580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6581   PetscValidType(mat,1);
6582   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6583   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6584   PetscValidPointer(info,4);
6585   PetscValidPointer(fact,5);
6586   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6587   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6588   if (!(fact)->ops->ilufactorsymbolic) {
6589     MatSolverType spackage;
6590     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6591     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6592   }
6593   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6594   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6595   MatCheckPreallocated(mat,2);
6596 
6597   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6598   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6599   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6600   PetscFunctionReturn(0);
6601 }
6602 
6603 /*@C
6604    MatICCFactorSymbolic - Performs symbolic incomplete
6605    Cholesky factorization for a symmetric matrix.  Use
6606    MatCholeskyFactorNumeric() to complete the factorization.
6607 
6608    Collective on Mat
6609 
6610    Input Parameters:
6611 +  mat - the matrix
6612 .  perm - row and column permutation
6613 -  info - structure containing
6614 $      levels - number of levels of fill.
6615 $      expected fill - as ratio of original fill.
6616 
6617    Output Parameter:
6618 .  fact - the factored matrix
6619 
6620    Notes:
6621    Most users should employ the KSP interface for linear solvers
6622    instead of working directly with matrix algebra routines such as this.
6623    See, e.g., KSPCreate().
6624 
6625    Level: developer
6626 
6627 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6628 
6629     Note: this uses the definition of level of fill as in Y. Saad, 2003
6630 
6631     Developer Note: fortran interface is not autogenerated as the f90
6632     interface defintion cannot be generated correctly [due to MatFactorInfo]
6633 
6634    References:
6635      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6636 @*/
6637 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6638 {
6639   PetscErrorCode ierr;
6640 
6641   PetscFunctionBegin;
6642   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6643   PetscValidType(mat,1);
6644   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6645   PetscValidPointer(info,3);
6646   PetscValidPointer(fact,4);
6647   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6648   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6649   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6650   if (!(fact)->ops->iccfactorsymbolic) {
6651     MatSolverType spackage;
6652     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6653     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6654   }
6655   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6656   MatCheckPreallocated(mat,2);
6657 
6658   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6659   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6660   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6661   PetscFunctionReturn(0);
6662 }
6663 
6664 /*@C
6665    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6666    points to an array of valid matrices, they may be reused to store the new
6667    submatrices.
6668 
6669    Collective on Mat
6670 
6671    Input Parameters:
6672 +  mat - the matrix
6673 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6674 .  irow, icol - index sets of rows and columns to extract
6675 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6676 
6677    Output Parameter:
6678 .  submat - the array of submatrices
6679 
6680    Notes:
6681    MatCreateSubMatrices() can extract ONLY sequential submatrices
6682    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6683    to extract a parallel submatrix.
6684 
6685    Some matrix types place restrictions on the row and column
6686    indices, such as that they be sorted or that they be equal to each other.
6687 
6688    The index sets may not have duplicate entries.
6689 
6690    When extracting submatrices from a parallel matrix, each processor can
6691    form a different submatrix by setting the rows and columns of its
6692    individual index sets according to the local submatrix desired.
6693 
6694    When finished using the submatrices, the user should destroy
6695    them with MatDestroySubMatrices().
6696 
6697    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6698    original matrix has not changed from that last call to MatCreateSubMatrices().
6699 
6700    This routine creates the matrices in submat; you should NOT create them before
6701    calling it. It also allocates the array of matrix pointers submat.
6702 
6703    For BAIJ matrices the index sets must respect the block structure, that is if they
6704    request one row/column in a block, they must request all rows/columns that are in
6705    that block. For example, if the block size is 2 you cannot request just row 0 and
6706    column 0.
6707 
6708    Fortran Note:
6709    The Fortran interface is slightly different from that given below; it
6710    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6711 
6712    Level: advanced
6713 
6714 
6715 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6716 @*/
6717 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6718 {
6719   PetscErrorCode ierr;
6720   PetscInt       i;
6721   PetscBool      eq;
6722 
6723   PetscFunctionBegin;
6724   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6725   PetscValidType(mat,1);
6726   if (n) {
6727     PetscValidPointer(irow,3);
6728     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6729     PetscValidPointer(icol,4);
6730     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6731   }
6732   PetscValidPointer(submat,6);
6733   if (n && scall == MAT_REUSE_MATRIX) {
6734     PetscValidPointer(*submat,6);
6735     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6736   }
6737   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6738   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6739   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6740   MatCheckPreallocated(mat,1);
6741 
6742   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6743   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6744   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6745   for (i=0; i<n; i++) {
6746     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6747     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6748       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6749       if (eq) {
6750         if (mat->symmetric) {
6751           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6752         } else if (mat->hermitian) {
6753           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6754         } else if (mat->structurally_symmetric) {
6755           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6756         }
6757       }
6758     }
6759   }
6760   PetscFunctionReturn(0);
6761 }
6762 
6763 /*@C
6764    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6765 
6766    Collective on Mat
6767 
6768    Input Parameters:
6769 +  mat - the matrix
6770 .  n   - the number of submatrixes to be extracted
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    Level: advanced
6778 
6779 
6780 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6781 @*/
6782 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6783 {
6784   PetscErrorCode ierr;
6785   PetscInt       i;
6786   PetscBool      eq;
6787 
6788   PetscFunctionBegin;
6789   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6790   PetscValidType(mat,1);
6791   if (n) {
6792     PetscValidPointer(irow,3);
6793     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6794     PetscValidPointer(icol,4);
6795     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6796   }
6797   PetscValidPointer(submat,6);
6798   if (n && scall == MAT_REUSE_MATRIX) {
6799     PetscValidPointer(*submat,6);
6800     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6801   }
6802   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6803   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6804   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6805   MatCheckPreallocated(mat,1);
6806 
6807   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6808   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6809   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6810   for (i=0; i<n; i++) {
6811     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6812       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6813       if (eq) {
6814         if (mat->symmetric) {
6815           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6816         } else if (mat->hermitian) {
6817           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6818         } else if (mat->structurally_symmetric) {
6819           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6820         }
6821       }
6822     }
6823   }
6824   PetscFunctionReturn(0);
6825 }
6826 
6827 /*@C
6828    MatDestroyMatrices - Destroys an array of matrices.
6829 
6830    Collective on Mat
6831 
6832    Input Parameters:
6833 +  n - the number of local matrices
6834 -  mat - the matrices (note that this is a pointer to the array of matrices)
6835 
6836    Level: advanced
6837 
6838     Notes:
6839     Frees not only the matrices, but also the array that contains the matrices
6840            In Fortran will not free the array.
6841 
6842 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6843 @*/
6844 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6845 {
6846   PetscErrorCode ierr;
6847   PetscInt       i;
6848 
6849   PetscFunctionBegin;
6850   if (!*mat) PetscFunctionReturn(0);
6851   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6852   PetscValidPointer(mat,2);
6853 
6854   for (i=0; i<n; i++) {
6855     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6856   }
6857 
6858   /* memory is allocated even if n = 0 */
6859   ierr = PetscFree(*mat);CHKERRQ(ierr);
6860   PetscFunctionReturn(0);
6861 }
6862 
6863 /*@C
6864    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6865 
6866    Collective on Mat
6867 
6868    Input Parameters:
6869 +  n - the number of local matrices
6870 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6871                        sequence of MatCreateSubMatrices())
6872 
6873    Level: advanced
6874 
6875     Notes:
6876     Frees not only the matrices, but also the array that contains the matrices
6877            In Fortran will not free the array.
6878 
6879 .seealso: MatCreateSubMatrices()
6880 @*/
6881 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6882 {
6883   PetscErrorCode ierr;
6884   Mat            mat0;
6885 
6886   PetscFunctionBegin;
6887   if (!*mat) PetscFunctionReturn(0);
6888   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6889   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6890   PetscValidPointer(mat,2);
6891 
6892   mat0 = (*mat)[0];
6893   if (mat0 && mat0->ops->destroysubmatrices) {
6894     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6895   } else {
6896     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6897   }
6898   PetscFunctionReturn(0);
6899 }
6900 
6901 /*@C
6902    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6903 
6904    Collective on Mat
6905 
6906    Input Parameters:
6907 .  mat - the matrix
6908 
6909    Output Parameter:
6910 .  matstruct - the sequential matrix with the nonzero structure of mat
6911 
6912   Level: intermediate
6913 
6914 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6915 @*/
6916 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6917 {
6918   PetscErrorCode ierr;
6919 
6920   PetscFunctionBegin;
6921   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6922   PetscValidPointer(matstruct,2);
6923 
6924   PetscValidType(mat,1);
6925   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6926   MatCheckPreallocated(mat,1);
6927 
6928   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6929   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6930   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6931   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6932   PetscFunctionReturn(0);
6933 }
6934 
6935 /*@C
6936    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6937 
6938    Collective on Mat
6939 
6940    Input Parameters:
6941 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6942                        sequence of MatGetSequentialNonzeroStructure())
6943 
6944    Level: advanced
6945 
6946     Notes:
6947     Frees not only the matrices, but also the array that contains the matrices
6948 
6949 .seealso: MatGetSeqNonzeroStructure()
6950 @*/
6951 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6952 {
6953   PetscErrorCode ierr;
6954 
6955   PetscFunctionBegin;
6956   PetscValidPointer(mat,1);
6957   ierr = MatDestroy(mat);CHKERRQ(ierr);
6958   PetscFunctionReturn(0);
6959 }
6960 
6961 /*@
6962    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6963    replaces the index sets by larger ones that represent submatrices with
6964    additional overlap.
6965 
6966    Collective on Mat
6967 
6968    Input Parameters:
6969 +  mat - the matrix
6970 .  n   - the number of index sets
6971 .  is  - the array of index sets (these index sets will changed during the call)
6972 -  ov  - the additional overlap requested
6973 
6974    Options Database:
6975 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6976 
6977    Level: developer
6978 
6979 
6980 .seealso: MatCreateSubMatrices()
6981 @*/
6982 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6983 {
6984   PetscErrorCode ierr;
6985 
6986   PetscFunctionBegin;
6987   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6988   PetscValidType(mat,1);
6989   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6990   if (n) {
6991     PetscValidPointer(is,3);
6992     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6993   }
6994   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6995   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6996   MatCheckPreallocated(mat,1);
6997 
6998   if (!ov) PetscFunctionReturn(0);
6999   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7000   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7001   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7002   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7003   PetscFunctionReturn(0);
7004 }
7005 
7006 
7007 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7008 
7009 /*@
7010    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7011    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7012    additional overlap.
7013 
7014    Collective on Mat
7015 
7016    Input Parameters:
7017 +  mat - the matrix
7018 .  n   - the number of index sets
7019 .  is  - the array of index sets (these index sets will changed during the call)
7020 -  ov  - the additional overlap requested
7021 
7022    Options Database:
7023 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7024 
7025    Level: developer
7026 
7027 
7028 .seealso: MatCreateSubMatrices()
7029 @*/
7030 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7031 {
7032   PetscInt       i;
7033   PetscErrorCode ierr;
7034 
7035   PetscFunctionBegin;
7036   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7037   PetscValidType(mat,1);
7038   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7039   if (n) {
7040     PetscValidPointer(is,3);
7041     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7042   }
7043   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7044   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7045   MatCheckPreallocated(mat,1);
7046   if (!ov) PetscFunctionReturn(0);
7047   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7048   for(i=0; i<n; i++){
7049 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7050   }
7051   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7052   PetscFunctionReturn(0);
7053 }
7054 
7055 
7056 
7057 
7058 /*@
7059    MatGetBlockSize - Returns the matrix block size.
7060 
7061    Not Collective
7062 
7063    Input Parameter:
7064 .  mat - the matrix
7065 
7066    Output Parameter:
7067 .  bs - block size
7068 
7069    Notes:
7070     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7071 
7072    If the block size has not been set yet this routine returns 1.
7073 
7074    Level: intermediate
7075 
7076 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7077 @*/
7078 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7079 {
7080   PetscFunctionBegin;
7081   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7082   PetscValidIntPointer(bs,2);
7083   *bs = PetscAbs(mat->rmap->bs);
7084   PetscFunctionReturn(0);
7085 }
7086 
7087 /*@
7088    MatGetBlockSizes - Returns the matrix block row and column sizes.
7089 
7090    Not Collective
7091 
7092    Input Parameter:
7093 .  mat - the matrix
7094 
7095    Output Parameter:
7096 +  rbs - row block size
7097 -  cbs - column block size
7098 
7099    Notes:
7100     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7101     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7102 
7103    If a block size has not been set yet this routine returns 1.
7104 
7105    Level: intermediate
7106 
7107 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7108 @*/
7109 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7110 {
7111   PetscFunctionBegin;
7112   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7113   if (rbs) PetscValidIntPointer(rbs,2);
7114   if (cbs) PetscValidIntPointer(cbs,3);
7115   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7116   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7117   PetscFunctionReturn(0);
7118 }
7119 
7120 /*@
7121    MatSetBlockSize - Sets the matrix block size.
7122 
7123    Logically Collective on Mat
7124 
7125    Input Parameters:
7126 +  mat - the matrix
7127 -  bs - block size
7128 
7129    Notes:
7130     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7131     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7132 
7133     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7134     is compatible with the matrix local sizes.
7135 
7136    Level: intermediate
7137 
7138 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7139 @*/
7140 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7141 {
7142   PetscErrorCode ierr;
7143 
7144   PetscFunctionBegin;
7145   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7146   PetscValidLogicalCollectiveInt(mat,bs,2);
7147   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7148   PetscFunctionReturn(0);
7149 }
7150 
7151 /*@
7152    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7153 
7154    Logically Collective on Mat
7155 
7156    Input Parameters:
7157 +  mat - the matrix
7158 .  nblocks - the number of blocks on this process
7159 -  bsizes - the block sizes
7160 
7161    Notes:
7162     Currently used by PCVPBJACOBI for SeqAIJ matrices
7163 
7164    Level: intermediate
7165 
7166 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7167 @*/
7168 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7169 {
7170   PetscErrorCode ierr;
7171   PetscInt       i,ncnt = 0, nlocal;
7172 
7173   PetscFunctionBegin;
7174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7175   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7176   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7177   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7178   if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7179   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7180   mat->nblocks = nblocks;
7181   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7182   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7183   PetscFunctionReturn(0);
7184 }
7185 
7186 /*@C
7187    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7188 
7189    Logically Collective on Mat
7190 
7191    Input Parameters:
7192 .  mat - the matrix
7193 
7194    Output Parameters:
7195 +  nblocks - the number of blocks on this process
7196 -  bsizes - the block sizes
7197 
7198    Notes: Currently not supported from Fortran
7199 
7200    Level: intermediate
7201 
7202 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7203 @*/
7204 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7205 {
7206   PetscFunctionBegin;
7207   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7208   *nblocks = mat->nblocks;
7209   *bsizes  = mat->bsizes;
7210   PetscFunctionReturn(0);
7211 }
7212 
7213 /*@
7214    MatSetBlockSizes - Sets the matrix block row and column sizes.
7215 
7216    Logically Collective on Mat
7217 
7218    Input Parameters:
7219 +  mat - the matrix
7220 -  rbs - row block size
7221 -  cbs - column block size
7222 
7223    Notes:
7224     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7225     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7226     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7227 
7228     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7229     are compatible with the matrix local sizes.
7230 
7231     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7232 
7233    Level: intermediate
7234 
7235 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7236 @*/
7237 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7238 {
7239   PetscErrorCode ierr;
7240 
7241   PetscFunctionBegin;
7242   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7243   PetscValidLogicalCollectiveInt(mat,rbs,2);
7244   PetscValidLogicalCollectiveInt(mat,cbs,3);
7245   if (mat->ops->setblocksizes) {
7246     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7247   }
7248   if (mat->rmap->refcnt) {
7249     ISLocalToGlobalMapping l2g = NULL;
7250     PetscLayout            nmap = NULL;
7251 
7252     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7253     if (mat->rmap->mapping) {
7254       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7255     }
7256     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7257     mat->rmap = nmap;
7258     mat->rmap->mapping = l2g;
7259   }
7260   if (mat->cmap->refcnt) {
7261     ISLocalToGlobalMapping l2g = NULL;
7262     PetscLayout            nmap = NULL;
7263 
7264     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7265     if (mat->cmap->mapping) {
7266       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7267     }
7268     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7269     mat->cmap = nmap;
7270     mat->cmap->mapping = l2g;
7271   }
7272   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7273   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7274   PetscFunctionReturn(0);
7275 }
7276 
7277 /*@
7278    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7279 
7280    Logically Collective on Mat
7281 
7282    Input Parameters:
7283 +  mat - the matrix
7284 .  fromRow - matrix from which to copy row block size
7285 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7286 
7287    Level: developer
7288 
7289 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7290 @*/
7291 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7292 {
7293   PetscErrorCode ierr;
7294 
7295   PetscFunctionBegin;
7296   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7297   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7298   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7299   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7300   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7301   PetscFunctionReturn(0);
7302 }
7303 
7304 /*@
7305    MatResidual - Default routine to calculate the residual.
7306 
7307    Collective on Mat
7308 
7309    Input Parameters:
7310 +  mat - the matrix
7311 .  b   - the right-hand-side
7312 -  x   - the approximate solution
7313 
7314    Output Parameter:
7315 .  r - location to store the residual
7316 
7317    Level: developer
7318 
7319 .seealso: PCMGSetResidual()
7320 @*/
7321 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7322 {
7323   PetscErrorCode ierr;
7324 
7325   PetscFunctionBegin;
7326   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7327   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7328   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7329   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7330   PetscValidType(mat,1);
7331   MatCheckPreallocated(mat,1);
7332   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7333   if (!mat->ops->residual) {
7334     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7335     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7336   } else {
7337     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7338   }
7339   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7340   PetscFunctionReturn(0);
7341 }
7342 
7343 /*@C
7344     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7345 
7346    Collective on Mat
7347 
7348     Input Parameters:
7349 +   mat - the matrix
7350 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7351 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7352 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7353                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7354                  always used.
7355 
7356     Output Parameters:
7357 +   n - number of rows in the (possibly compressed) matrix
7358 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7359 .   ja - the column indices
7360 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7361            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7362 
7363     Level: developer
7364 
7365     Notes:
7366     You CANNOT change any of the ia[] or ja[] values.
7367 
7368     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7369 
7370     Fortran Notes:
7371     In Fortran use
7372 $
7373 $      PetscInt ia(1), ja(1)
7374 $      PetscOffset iia, jja
7375 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7376 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7377 
7378      or
7379 $
7380 $    PetscInt, pointer :: ia(:),ja(:)
7381 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7382 $    ! Access the ith and jth entries via ia(i) and ja(j)
7383 
7384 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7385 @*/
7386 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7387 {
7388   PetscErrorCode ierr;
7389 
7390   PetscFunctionBegin;
7391   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7392   PetscValidType(mat,1);
7393   PetscValidIntPointer(n,5);
7394   if (ia) PetscValidIntPointer(ia,6);
7395   if (ja) PetscValidIntPointer(ja,7);
7396   PetscValidIntPointer(done,8);
7397   MatCheckPreallocated(mat,1);
7398   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7399   else {
7400     *done = PETSC_TRUE;
7401     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7402     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7403     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7404   }
7405   PetscFunctionReturn(0);
7406 }
7407 
7408 /*@C
7409     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7410 
7411     Collective on Mat
7412 
7413     Input Parameters:
7414 +   mat - the matrix
7415 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7416 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7417                 symmetrized
7418 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7419                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7420                  always used.
7421 .   n - number of columns in the (possibly compressed) matrix
7422 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7423 -   ja - the row indices
7424 
7425     Output Parameters:
7426 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7427 
7428     Level: developer
7429 
7430 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7431 @*/
7432 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7433 {
7434   PetscErrorCode ierr;
7435 
7436   PetscFunctionBegin;
7437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7438   PetscValidType(mat,1);
7439   PetscValidIntPointer(n,4);
7440   if (ia) PetscValidIntPointer(ia,5);
7441   if (ja) PetscValidIntPointer(ja,6);
7442   PetscValidIntPointer(done,7);
7443   MatCheckPreallocated(mat,1);
7444   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7445   else {
7446     *done = PETSC_TRUE;
7447     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7448   }
7449   PetscFunctionReturn(0);
7450 }
7451 
7452 /*@C
7453     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7454     MatGetRowIJ().
7455 
7456     Collective on Mat
7457 
7458     Input Parameters:
7459 +   mat - the matrix
7460 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7461 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7462                 symmetrized
7463 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7464                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7465                  always used.
7466 .   n - size of (possibly compressed) matrix
7467 .   ia - the row pointers
7468 -   ja - the column indices
7469 
7470     Output Parameters:
7471 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7472 
7473     Note:
7474     This routine zeros out n, ia, and ja. This is to prevent accidental
7475     us of the array after it has been restored. If you pass NULL, it will
7476     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7477 
7478     Level: developer
7479 
7480 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7481 @*/
7482 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7483 {
7484   PetscErrorCode ierr;
7485 
7486   PetscFunctionBegin;
7487   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7488   PetscValidType(mat,1);
7489   if (ia) PetscValidIntPointer(ia,6);
7490   if (ja) PetscValidIntPointer(ja,7);
7491   PetscValidIntPointer(done,8);
7492   MatCheckPreallocated(mat,1);
7493 
7494   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7495   else {
7496     *done = PETSC_TRUE;
7497     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7498     if (n)  *n = 0;
7499     if (ia) *ia = NULL;
7500     if (ja) *ja = NULL;
7501   }
7502   PetscFunctionReturn(0);
7503 }
7504 
7505 /*@C
7506     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7507     MatGetColumnIJ().
7508 
7509     Collective on Mat
7510 
7511     Input Parameters:
7512 +   mat - the matrix
7513 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7514 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7515                 symmetrized
7516 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7517                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7518                  always used.
7519 
7520     Output Parameters:
7521 +   n - size of (possibly compressed) matrix
7522 .   ia - the column pointers
7523 .   ja - the row indices
7524 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7525 
7526     Level: developer
7527 
7528 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7529 @*/
7530 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7531 {
7532   PetscErrorCode ierr;
7533 
7534   PetscFunctionBegin;
7535   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7536   PetscValidType(mat,1);
7537   if (ia) PetscValidIntPointer(ia,5);
7538   if (ja) PetscValidIntPointer(ja,6);
7539   PetscValidIntPointer(done,7);
7540   MatCheckPreallocated(mat,1);
7541 
7542   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7543   else {
7544     *done = PETSC_TRUE;
7545     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7546     if (n)  *n = 0;
7547     if (ia) *ia = NULL;
7548     if (ja) *ja = NULL;
7549   }
7550   PetscFunctionReturn(0);
7551 }
7552 
7553 /*@C
7554     MatColoringPatch -Used inside matrix coloring routines that
7555     use MatGetRowIJ() and/or MatGetColumnIJ().
7556 
7557     Collective on Mat
7558 
7559     Input Parameters:
7560 +   mat - the matrix
7561 .   ncolors - max color value
7562 .   n   - number of entries in colorarray
7563 -   colorarray - array indicating color for each column
7564 
7565     Output Parameters:
7566 .   iscoloring - coloring generated using colorarray information
7567 
7568     Level: developer
7569 
7570 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7571 
7572 @*/
7573 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7574 {
7575   PetscErrorCode ierr;
7576 
7577   PetscFunctionBegin;
7578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7579   PetscValidType(mat,1);
7580   PetscValidIntPointer(colorarray,4);
7581   PetscValidPointer(iscoloring,5);
7582   MatCheckPreallocated(mat,1);
7583 
7584   if (!mat->ops->coloringpatch) {
7585     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7586   } else {
7587     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7588   }
7589   PetscFunctionReturn(0);
7590 }
7591 
7592 
7593 /*@
7594    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7595 
7596    Logically Collective on Mat
7597 
7598    Input Parameter:
7599 .  mat - the factored matrix to be reset
7600 
7601    Notes:
7602    This routine should be used only with factored matrices formed by in-place
7603    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7604    format).  This option can save memory, for example, when solving nonlinear
7605    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7606    ILU(0) preconditioner.
7607 
7608    Note that one can specify in-place ILU(0) factorization by calling
7609 .vb
7610      PCType(pc,PCILU);
7611      PCFactorSeUseInPlace(pc);
7612 .ve
7613    or by using the options -pc_type ilu -pc_factor_in_place
7614 
7615    In-place factorization ILU(0) can also be used as a local
7616    solver for the blocks within the block Jacobi or additive Schwarz
7617    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7618    for details on setting local solver options.
7619 
7620    Most users should employ the simplified KSP interface for linear solvers
7621    instead of working directly with matrix algebra routines such as this.
7622    See, e.g., KSPCreate().
7623 
7624    Level: developer
7625 
7626 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7627 
7628 @*/
7629 PetscErrorCode MatSetUnfactored(Mat mat)
7630 {
7631   PetscErrorCode ierr;
7632 
7633   PetscFunctionBegin;
7634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7635   PetscValidType(mat,1);
7636   MatCheckPreallocated(mat,1);
7637   mat->factortype = MAT_FACTOR_NONE;
7638   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7639   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7640   PetscFunctionReturn(0);
7641 }
7642 
7643 /*MC
7644     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7645 
7646     Synopsis:
7647     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7648 
7649     Not collective
7650 
7651     Input Parameter:
7652 .   x - matrix
7653 
7654     Output Parameters:
7655 +   xx_v - the Fortran90 pointer to the array
7656 -   ierr - error code
7657 
7658     Example of Usage:
7659 .vb
7660       PetscScalar, pointer xx_v(:,:)
7661       ....
7662       call MatDenseGetArrayF90(x,xx_v,ierr)
7663       a = xx_v(3)
7664       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7665 .ve
7666 
7667     Level: advanced
7668 
7669 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7670 
7671 M*/
7672 
7673 /*MC
7674     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7675     accessed with MatDenseGetArrayF90().
7676 
7677     Synopsis:
7678     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7679 
7680     Not collective
7681 
7682     Input Parameters:
7683 +   x - matrix
7684 -   xx_v - the Fortran90 pointer to the array
7685 
7686     Output Parameter:
7687 .   ierr - error code
7688 
7689     Example of Usage:
7690 .vb
7691        PetscScalar, pointer xx_v(:,:)
7692        ....
7693        call MatDenseGetArrayF90(x,xx_v,ierr)
7694        a = xx_v(3)
7695        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7696 .ve
7697 
7698     Level: advanced
7699 
7700 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7701 
7702 M*/
7703 
7704 
7705 /*MC
7706     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7707 
7708     Synopsis:
7709     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7710 
7711     Not collective
7712 
7713     Input Parameter:
7714 .   x - matrix
7715 
7716     Output Parameters:
7717 +   xx_v - the Fortran90 pointer to the array
7718 -   ierr - error code
7719 
7720     Example of Usage:
7721 .vb
7722       PetscScalar, pointer xx_v(:)
7723       ....
7724       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7725       a = xx_v(3)
7726       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7727 .ve
7728 
7729     Level: advanced
7730 
7731 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7732 
7733 M*/
7734 
7735 /*MC
7736     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7737     accessed with MatSeqAIJGetArrayF90().
7738 
7739     Synopsis:
7740     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7741 
7742     Not collective
7743 
7744     Input Parameters:
7745 +   x - matrix
7746 -   xx_v - the Fortran90 pointer to the array
7747 
7748     Output Parameter:
7749 .   ierr - error code
7750 
7751     Example of Usage:
7752 .vb
7753        PetscScalar, pointer xx_v(:)
7754        ....
7755        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7756        a = xx_v(3)
7757        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7758 .ve
7759 
7760     Level: advanced
7761 
7762 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7763 
7764 M*/
7765 
7766 
7767 /*@
7768     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7769                       as the original matrix.
7770 
7771     Collective on Mat
7772 
7773     Input Parameters:
7774 +   mat - the original matrix
7775 .   isrow - parallel IS containing the rows this processor should obtain
7776 .   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.
7777 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7778 
7779     Output Parameter:
7780 .   newmat - the new submatrix, of the same type as the old
7781 
7782     Level: advanced
7783 
7784     Notes:
7785     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7786 
7787     Some matrix types place restrictions on the row and column indices, such
7788     as that they be sorted or that they be equal to each other.
7789 
7790     The index sets may not have duplicate entries.
7791 
7792       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7793    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7794    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7795    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7796    you are finished using it.
7797 
7798     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7799     the input matrix.
7800 
7801     If iscol is NULL then all columns are obtained (not supported in Fortran).
7802 
7803    Example usage:
7804    Consider the following 8x8 matrix with 34 non-zero values, that is
7805    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7806    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7807    as follows:
7808 
7809 .vb
7810             1  2  0  |  0  3  0  |  0  4
7811     Proc0   0  5  6  |  7  0  0  |  8  0
7812             9  0 10  | 11  0  0  | 12  0
7813     -------------------------------------
7814            13  0 14  | 15 16 17  |  0  0
7815     Proc1   0 18  0  | 19 20 21  |  0  0
7816             0  0  0  | 22 23  0  | 24  0
7817     -------------------------------------
7818     Proc2  25 26 27  |  0  0 28  | 29  0
7819            30  0  0  | 31 32 33  |  0 34
7820 .ve
7821 
7822     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7823 
7824 .vb
7825             2  0  |  0  3  0  |  0
7826     Proc0   5  6  |  7  0  0  |  8
7827     -------------------------------
7828     Proc1  18  0  | 19 20 21  |  0
7829     -------------------------------
7830     Proc2  26 27  |  0  0 28  | 29
7831             0  0  | 31 32 33  |  0
7832 .ve
7833 
7834 
7835 .seealso: MatCreateSubMatrices()
7836 @*/
7837 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7838 {
7839   PetscErrorCode ierr;
7840   PetscMPIInt    size;
7841   Mat            *local;
7842   IS             iscoltmp;
7843 
7844   PetscFunctionBegin;
7845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7846   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7847   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7848   PetscValidPointer(newmat,5);
7849   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7850   PetscValidType(mat,1);
7851   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7852   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7853 
7854   MatCheckPreallocated(mat,1);
7855   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7856 
7857   if (!iscol || isrow == iscol) {
7858     PetscBool   stride;
7859     PetscMPIInt grabentirematrix = 0,grab;
7860     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7861     if (stride) {
7862       PetscInt first,step,n,rstart,rend;
7863       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7864       if (step == 1) {
7865         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7866         if (rstart == first) {
7867           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7868           if (n == rend-rstart) {
7869             grabentirematrix = 1;
7870           }
7871         }
7872       }
7873     }
7874     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7875     if (grab) {
7876       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7877       if (cll == MAT_INITIAL_MATRIX) {
7878         *newmat = mat;
7879         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7880       }
7881       PetscFunctionReturn(0);
7882     }
7883   }
7884 
7885   if (!iscol) {
7886     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7887   } else {
7888     iscoltmp = iscol;
7889   }
7890 
7891   /* if original matrix is on just one processor then use submatrix generated */
7892   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7893     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7894     goto setproperties;
7895   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7896     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7897     *newmat = *local;
7898     ierr    = PetscFree(local);CHKERRQ(ierr);
7899     goto setproperties;
7900   } else if (!mat->ops->createsubmatrix) {
7901     /* Create a new matrix type that implements the operation using the full matrix */
7902     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7903     switch (cll) {
7904     case MAT_INITIAL_MATRIX:
7905       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7906       break;
7907     case MAT_REUSE_MATRIX:
7908       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7909       break;
7910     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7911     }
7912     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7913     goto setproperties;
7914   }
7915 
7916   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7917   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7918   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7919   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7920 
7921   /* Propagate symmetry information for diagonal blocks */
7922 setproperties:
7923   if (isrow == iscoltmp) {
7924     if (mat->symmetric_set && mat->symmetric) {
7925       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7926     }
7927     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
7928       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7929     }
7930     if (mat->hermitian_set && mat->hermitian) {
7931       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7932     }
7933     if (mat->spd_set && mat->spd) {
7934       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
7935     }
7936   }
7937 
7938   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7939   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7940   PetscFunctionReturn(0);
7941 }
7942 
7943 /*@
7944    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7945    used during the assembly process to store values that belong to
7946    other processors.
7947 
7948    Not Collective
7949 
7950    Input Parameters:
7951 +  mat   - the matrix
7952 .  size  - the initial size of the stash.
7953 -  bsize - the initial size of the block-stash(if used).
7954 
7955    Options Database Keys:
7956 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7957 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7958 
7959    Level: intermediate
7960 
7961    Notes:
7962      The block-stash is used for values set with MatSetValuesBlocked() while
7963      the stash is used for values set with MatSetValues()
7964 
7965      Run with the option -info and look for output of the form
7966      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7967      to determine the appropriate value, MM, to use for size and
7968      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7969      to determine the value, BMM to use for bsize
7970 
7971 
7972 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7973 
7974 @*/
7975 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7976 {
7977   PetscErrorCode ierr;
7978 
7979   PetscFunctionBegin;
7980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7981   PetscValidType(mat,1);
7982   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7983   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7984   PetscFunctionReturn(0);
7985 }
7986 
7987 /*@
7988    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7989      the matrix
7990 
7991    Neighbor-wise Collective on Mat
7992 
7993    Input Parameters:
7994 +  mat   - the matrix
7995 .  x,y - the vectors
7996 -  w - where the result is stored
7997 
7998    Level: intermediate
7999 
8000    Notes:
8001     w may be the same vector as y.
8002 
8003     This allows one to use either the restriction or interpolation (its transpose)
8004     matrix to do the interpolation
8005 
8006 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8007 
8008 @*/
8009 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8010 {
8011   PetscErrorCode ierr;
8012   PetscInt       M,N,Ny;
8013 
8014   PetscFunctionBegin;
8015   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8016   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8017   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8018   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8019   PetscValidType(A,1);
8020   MatCheckPreallocated(A,1);
8021   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8022   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8023   if (M == Ny) {
8024     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8025   } else {
8026     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8027   }
8028   PetscFunctionReturn(0);
8029 }
8030 
8031 /*@
8032    MatInterpolate - y = A*x or A'*x depending on the shape of
8033      the matrix
8034 
8035    Neighbor-wise Collective on Mat
8036 
8037    Input Parameters:
8038 +  mat   - the matrix
8039 -  x,y - the vectors
8040 
8041    Level: intermediate
8042 
8043    Notes:
8044     This allows one to use either the restriction or interpolation (its transpose)
8045     matrix to do the interpolation
8046 
8047 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8048 
8049 @*/
8050 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8051 {
8052   PetscErrorCode ierr;
8053   PetscInt       M,N,Ny;
8054 
8055   PetscFunctionBegin;
8056   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8057   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8058   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8059   PetscValidType(A,1);
8060   MatCheckPreallocated(A,1);
8061   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8062   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8063   if (M == Ny) {
8064     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8065   } else {
8066     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8067   }
8068   PetscFunctionReturn(0);
8069 }
8070 
8071 /*@
8072    MatRestrict - y = A*x or A'*x
8073 
8074    Neighbor-wise Collective on Mat
8075 
8076    Input Parameters:
8077 +  mat   - the matrix
8078 -  x,y - the vectors
8079 
8080    Level: intermediate
8081 
8082    Notes:
8083     This allows one to use either the restriction or interpolation (its transpose)
8084     matrix to do the restriction
8085 
8086 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8087 
8088 @*/
8089 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8090 {
8091   PetscErrorCode ierr;
8092   PetscInt       M,N,Ny;
8093 
8094   PetscFunctionBegin;
8095   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8096   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8097   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8098   PetscValidType(A,1);
8099   MatCheckPreallocated(A,1);
8100 
8101   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8102   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8103   if (M == Ny) {
8104     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8105   } else {
8106     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8107   }
8108   PetscFunctionReturn(0);
8109 }
8110 
8111 /*@
8112    MatGetNullSpace - retrieves the null space of a matrix.
8113 
8114    Logically Collective on Mat
8115 
8116    Input Parameters:
8117 +  mat - the matrix
8118 -  nullsp - the null space object
8119 
8120    Level: developer
8121 
8122 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8123 @*/
8124 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8125 {
8126   PetscFunctionBegin;
8127   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8128   PetscValidPointer(nullsp,2);
8129   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8130   PetscFunctionReturn(0);
8131 }
8132 
8133 /*@
8134    MatSetNullSpace - attaches a null space to a matrix.
8135 
8136    Logically Collective on Mat
8137 
8138    Input Parameters:
8139 +  mat - the matrix
8140 -  nullsp - the null space object
8141 
8142    Level: advanced
8143 
8144    Notes:
8145       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8146 
8147       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8148       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8149 
8150       You can remove the null space by calling this routine with an nullsp of NULL
8151 
8152 
8153       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8154    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).
8155    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
8156    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
8157    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).
8158 
8159       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8160 
8161     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
8162     routine also automatically calls MatSetTransposeNullSpace().
8163 
8164 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8165 @*/
8166 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8167 {
8168   PetscErrorCode ierr;
8169 
8170   PetscFunctionBegin;
8171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8172   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8173   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8174   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8175   mat->nullsp = nullsp;
8176   if (mat->symmetric_set && mat->symmetric) {
8177     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8178   }
8179   PetscFunctionReturn(0);
8180 }
8181 
8182 /*@
8183    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8184 
8185    Logically Collective on Mat
8186 
8187    Input Parameters:
8188 +  mat - the matrix
8189 -  nullsp - the null space object
8190 
8191    Level: developer
8192 
8193 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8194 @*/
8195 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8196 {
8197   PetscFunctionBegin;
8198   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8199   PetscValidType(mat,1);
8200   PetscValidPointer(nullsp,2);
8201   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8202   PetscFunctionReturn(0);
8203 }
8204 
8205 /*@
8206    MatSetTransposeNullSpace - attaches a null space to a matrix.
8207 
8208    Logically Collective on Mat
8209 
8210    Input Parameters:
8211 +  mat - the matrix
8212 -  nullsp - the null space object
8213 
8214    Level: advanced
8215 
8216    Notes:
8217       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8218       You must also call MatSetNullSpace()
8219 
8220 
8221       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8222    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8223    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8224    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8225    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8226 
8227       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8228 
8229 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8230 @*/
8231 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8232 {
8233   PetscErrorCode ierr;
8234 
8235   PetscFunctionBegin;
8236   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8237   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8238   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8239   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8240   mat->transnullsp = nullsp;
8241   PetscFunctionReturn(0);
8242 }
8243 
8244 /*@
8245    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8246         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8247 
8248    Logically Collective on Mat
8249 
8250    Input Parameters:
8251 +  mat - the matrix
8252 -  nullsp - the null space object
8253 
8254    Level: advanced
8255 
8256    Notes:
8257       Overwrites any previous near null space that may have been attached
8258 
8259       You can remove the null space by calling this routine with an nullsp of NULL
8260 
8261 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8262 @*/
8263 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8264 {
8265   PetscErrorCode ierr;
8266 
8267   PetscFunctionBegin;
8268   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8269   PetscValidType(mat,1);
8270   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8271   MatCheckPreallocated(mat,1);
8272   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8273   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8274   mat->nearnullsp = nullsp;
8275   PetscFunctionReturn(0);
8276 }
8277 
8278 /*@
8279    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8280 
8281    Not Collective
8282 
8283    Input Parameters:
8284 .  mat - the matrix
8285 
8286    Output Parameters:
8287 .  nullsp - the null space object, NULL if not set
8288 
8289    Level: developer
8290 
8291 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8292 @*/
8293 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8294 {
8295   PetscFunctionBegin;
8296   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8297   PetscValidType(mat,1);
8298   PetscValidPointer(nullsp,2);
8299   MatCheckPreallocated(mat,1);
8300   *nullsp = mat->nearnullsp;
8301   PetscFunctionReturn(0);
8302 }
8303 
8304 /*@C
8305    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8306 
8307    Collective on Mat
8308 
8309    Input Parameters:
8310 +  mat - the matrix
8311 .  row - row/column permutation
8312 .  fill - expected fill factor >= 1.0
8313 -  level - level of fill, for ICC(k)
8314 
8315    Notes:
8316    Probably really in-place only when level of fill is zero, otherwise allocates
8317    new space to store factored matrix and deletes previous memory.
8318 
8319    Most users should employ the simplified KSP interface for linear solvers
8320    instead of working directly with matrix algebra routines such as this.
8321    See, e.g., KSPCreate().
8322 
8323    Level: developer
8324 
8325 
8326 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8327 
8328     Developer Note: fortran interface is not autogenerated as the f90
8329     interface defintion cannot be generated correctly [due to MatFactorInfo]
8330 
8331 @*/
8332 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8333 {
8334   PetscErrorCode ierr;
8335 
8336   PetscFunctionBegin;
8337   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8338   PetscValidType(mat,1);
8339   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8340   PetscValidPointer(info,3);
8341   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8342   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8343   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8344   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8345   MatCheckPreallocated(mat,1);
8346   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8347   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8348   PetscFunctionReturn(0);
8349 }
8350 
8351 /*@
8352    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8353          ghosted ones.
8354 
8355    Not Collective
8356 
8357    Input Parameters:
8358 +  mat - the matrix
8359 -  diag = the diagonal values, including ghost ones
8360 
8361    Level: developer
8362 
8363    Notes:
8364     Works only for MPIAIJ and MPIBAIJ matrices
8365 
8366 .seealso: MatDiagonalScale()
8367 @*/
8368 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8369 {
8370   PetscErrorCode ierr;
8371   PetscMPIInt    size;
8372 
8373   PetscFunctionBegin;
8374   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8375   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8376   PetscValidType(mat,1);
8377 
8378   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8379   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8380   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8381   if (size == 1) {
8382     PetscInt n,m;
8383     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8384     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8385     if (m == n) {
8386       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8387     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8388   } else {
8389     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8390   }
8391   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8392   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8393   PetscFunctionReturn(0);
8394 }
8395 
8396 /*@
8397    MatGetInertia - Gets the inertia from a factored matrix
8398 
8399    Collective on Mat
8400 
8401    Input Parameter:
8402 .  mat - the matrix
8403 
8404    Output Parameters:
8405 +   nneg - number of negative eigenvalues
8406 .   nzero - number of zero eigenvalues
8407 -   npos - number of positive eigenvalues
8408 
8409    Level: advanced
8410 
8411    Notes:
8412     Matrix must have been factored by MatCholeskyFactor()
8413 
8414 
8415 @*/
8416 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8417 {
8418   PetscErrorCode ierr;
8419 
8420   PetscFunctionBegin;
8421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8422   PetscValidType(mat,1);
8423   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8425   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8426   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8427   PetscFunctionReturn(0);
8428 }
8429 
8430 /* ----------------------------------------------------------------*/
8431 /*@C
8432    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8433 
8434    Neighbor-wise Collective on Mats
8435 
8436    Input Parameters:
8437 +  mat - the factored matrix
8438 -  b - the right-hand-side vectors
8439 
8440    Output Parameter:
8441 .  x - the result vectors
8442 
8443    Notes:
8444    The vectors b and x cannot be the same.  I.e., one cannot
8445    call MatSolves(A,x,x).
8446 
8447    Notes:
8448    Most users should employ the simplified KSP interface for linear solvers
8449    instead of working directly with matrix algebra routines such as this.
8450    See, e.g., KSPCreate().
8451 
8452    Level: developer
8453 
8454 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8455 @*/
8456 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8457 {
8458   PetscErrorCode ierr;
8459 
8460   PetscFunctionBegin;
8461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8462   PetscValidType(mat,1);
8463   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8464   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8465   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8466 
8467   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8468   MatCheckPreallocated(mat,1);
8469   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8470   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8471   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8472   PetscFunctionReturn(0);
8473 }
8474 
8475 /*@
8476    MatIsSymmetric - Test whether a matrix is symmetric
8477 
8478    Collective on Mat
8479 
8480    Input Parameter:
8481 +  A - the matrix to test
8482 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8483 
8484    Output Parameters:
8485 .  flg - the result
8486 
8487    Notes:
8488     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8489 
8490    Level: intermediate
8491 
8492 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8493 @*/
8494 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8495 {
8496   PetscErrorCode ierr;
8497 
8498   PetscFunctionBegin;
8499   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8500   PetscValidBoolPointer(flg,2);
8501 
8502   if (!A->symmetric_set) {
8503     if (!A->ops->issymmetric) {
8504       MatType mattype;
8505       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8506       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8507     }
8508     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8509     if (!tol) {
8510       A->symmetric_set = PETSC_TRUE;
8511       A->symmetric     = *flg;
8512       if (A->symmetric) {
8513         A->structurally_symmetric_set = PETSC_TRUE;
8514         A->structurally_symmetric     = PETSC_TRUE;
8515       }
8516     }
8517   } else if (A->symmetric) {
8518     *flg = PETSC_TRUE;
8519   } else if (!tol) {
8520     *flg = PETSC_FALSE;
8521   } else {
8522     if (!A->ops->issymmetric) {
8523       MatType mattype;
8524       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8525       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8526     }
8527     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8528   }
8529   PetscFunctionReturn(0);
8530 }
8531 
8532 /*@
8533    MatIsHermitian - Test whether a matrix is Hermitian
8534 
8535    Collective on Mat
8536 
8537    Input Parameter:
8538 +  A - the matrix to test
8539 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8540 
8541    Output Parameters:
8542 .  flg - the result
8543 
8544    Level: intermediate
8545 
8546 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8547           MatIsSymmetricKnown(), MatIsSymmetric()
8548 @*/
8549 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8550 {
8551   PetscErrorCode ierr;
8552 
8553   PetscFunctionBegin;
8554   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8555   PetscValidBoolPointer(flg,2);
8556 
8557   if (!A->hermitian_set) {
8558     if (!A->ops->ishermitian) {
8559       MatType mattype;
8560       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8561       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8562     }
8563     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8564     if (!tol) {
8565       A->hermitian_set = PETSC_TRUE;
8566       A->hermitian     = *flg;
8567       if (A->hermitian) {
8568         A->structurally_symmetric_set = PETSC_TRUE;
8569         A->structurally_symmetric     = PETSC_TRUE;
8570       }
8571     }
8572   } else if (A->hermitian) {
8573     *flg = PETSC_TRUE;
8574   } else if (!tol) {
8575     *flg = PETSC_FALSE;
8576   } else {
8577     if (!A->ops->ishermitian) {
8578       MatType mattype;
8579       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8580       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8581     }
8582     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8583   }
8584   PetscFunctionReturn(0);
8585 }
8586 
8587 /*@
8588    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8589 
8590    Not Collective
8591 
8592    Input Parameter:
8593 .  A - the matrix to check
8594 
8595    Output Parameters:
8596 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8597 -  flg - the result
8598 
8599    Level: advanced
8600 
8601    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8602          if you want it explicitly checked
8603 
8604 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8605 @*/
8606 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8607 {
8608   PetscFunctionBegin;
8609   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8610   PetscValidPointer(set,2);
8611   PetscValidBoolPointer(flg,3);
8612   if (A->symmetric_set) {
8613     *set = PETSC_TRUE;
8614     *flg = A->symmetric;
8615   } else {
8616     *set = PETSC_FALSE;
8617   }
8618   PetscFunctionReturn(0);
8619 }
8620 
8621 /*@
8622    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8623 
8624    Not Collective
8625 
8626    Input Parameter:
8627 .  A - the matrix to check
8628 
8629    Output Parameters:
8630 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8631 -  flg - the result
8632 
8633    Level: advanced
8634 
8635    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8636          if you want it explicitly checked
8637 
8638 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8639 @*/
8640 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8641 {
8642   PetscFunctionBegin;
8643   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8644   PetscValidPointer(set,2);
8645   PetscValidBoolPointer(flg,3);
8646   if (A->hermitian_set) {
8647     *set = PETSC_TRUE;
8648     *flg = A->hermitian;
8649   } else {
8650     *set = PETSC_FALSE;
8651   }
8652   PetscFunctionReturn(0);
8653 }
8654 
8655 /*@
8656    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8657 
8658    Collective on Mat
8659 
8660    Input Parameter:
8661 .  A - the matrix to test
8662 
8663    Output Parameters:
8664 .  flg - the result
8665 
8666    Level: intermediate
8667 
8668 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8669 @*/
8670 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8671 {
8672   PetscErrorCode ierr;
8673 
8674   PetscFunctionBegin;
8675   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8676   PetscValidBoolPointer(flg,2);
8677   if (!A->structurally_symmetric_set) {
8678     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8679     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8680 
8681     A->structurally_symmetric_set = PETSC_TRUE;
8682   }
8683   *flg = A->structurally_symmetric;
8684   PetscFunctionReturn(0);
8685 }
8686 
8687 /*@
8688    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8689        to be communicated to other processors during the MatAssemblyBegin/End() process
8690 
8691     Not collective
8692 
8693    Input Parameter:
8694 .   vec - the vector
8695 
8696    Output Parameters:
8697 +   nstash   - the size of the stash
8698 .   reallocs - the number of additional mallocs incurred.
8699 .   bnstash   - the size of the block stash
8700 -   breallocs - the number of additional mallocs incurred.in the block stash
8701 
8702    Level: advanced
8703 
8704 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8705 
8706 @*/
8707 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8708 {
8709   PetscErrorCode ierr;
8710 
8711   PetscFunctionBegin;
8712   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8713   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8714   PetscFunctionReturn(0);
8715 }
8716 
8717 /*@C
8718    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8719      parallel layout
8720 
8721    Collective on Mat
8722 
8723    Input Parameter:
8724 .  mat - the matrix
8725 
8726    Output Parameter:
8727 +   right - (optional) vector that the matrix can be multiplied against
8728 -   left - (optional) vector that the matrix vector product can be stored in
8729 
8730    Notes:
8731     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().
8732 
8733   Notes:
8734     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8735 
8736   Level: advanced
8737 
8738 .seealso: MatCreate(), VecDestroy()
8739 @*/
8740 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8741 {
8742   PetscErrorCode ierr;
8743 
8744   PetscFunctionBegin;
8745   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8746   PetscValidType(mat,1);
8747   if (mat->ops->getvecs) {
8748     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8749   } else {
8750     PetscInt rbs,cbs;
8751     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8752     if (right) {
8753       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8754       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8755       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8756       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8757       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8758       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8759     }
8760     if (left) {
8761       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8762       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8763       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8764       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8765       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8766       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8767     }
8768   }
8769   PetscFunctionReturn(0);
8770 }
8771 
8772 /*@C
8773    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8774      with default values.
8775 
8776    Not Collective
8777 
8778    Input Parameters:
8779 .    info - the MatFactorInfo data structure
8780 
8781 
8782    Notes:
8783     The solvers are generally used through the KSP and PC objects, for example
8784           PCLU, PCILU, PCCHOLESKY, PCICC
8785 
8786    Level: developer
8787 
8788 .seealso: MatFactorInfo
8789 
8790     Developer Note: fortran interface is not autogenerated as the f90
8791     interface defintion cannot be generated correctly [due to MatFactorInfo]
8792 
8793 @*/
8794 
8795 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8796 {
8797   PetscErrorCode ierr;
8798 
8799   PetscFunctionBegin;
8800   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8801   PetscFunctionReturn(0);
8802 }
8803 
8804 /*@
8805    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8806 
8807    Collective on Mat
8808 
8809    Input Parameters:
8810 +  mat - the factored matrix
8811 -  is - the index set defining the Schur indices (0-based)
8812 
8813    Notes:
8814     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8815 
8816    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8817 
8818    Level: developer
8819 
8820 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8821           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8822 
8823 @*/
8824 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8825 {
8826   PetscErrorCode ierr,(*f)(Mat,IS);
8827 
8828   PetscFunctionBegin;
8829   PetscValidType(mat,1);
8830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8831   PetscValidType(is,2);
8832   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8833   PetscCheckSameComm(mat,1,is,2);
8834   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8835   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8836   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8837   if (mat->schur) {
8838     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8839   }
8840   ierr = (*f)(mat,is);CHKERRQ(ierr);
8841   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8842   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8843   PetscFunctionReturn(0);
8844 }
8845 
8846 /*@
8847   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8848 
8849    Logically Collective on Mat
8850 
8851    Input Parameters:
8852 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8853 .  S - location where to return the Schur complement, can be NULL
8854 -  status - the status of the Schur complement matrix, can be NULL
8855 
8856    Notes:
8857    You must call MatFactorSetSchurIS() before calling this routine.
8858 
8859    The routine provides a copy of the Schur matrix stored within the solver data structures.
8860    The caller must destroy the object when it is no longer needed.
8861    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8862 
8863    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)
8864 
8865    Developer Notes:
8866     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8867    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8868 
8869    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8870 
8871    Level: advanced
8872 
8873    References:
8874 
8875 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8876 @*/
8877 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8878 {
8879   PetscErrorCode ierr;
8880 
8881   PetscFunctionBegin;
8882   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8883   if (S) PetscValidPointer(S,2);
8884   if (status) PetscValidPointer(status,3);
8885   if (S) {
8886     PetscErrorCode (*f)(Mat,Mat*);
8887 
8888     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8889     if (f) {
8890       ierr = (*f)(F,S);CHKERRQ(ierr);
8891     } else {
8892       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8893     }
8894   }
8895   if (status) *status = F->schur_status;
8896   PetscFunctionReturn(0);
8897 }
8898 
8899 /*@
8900   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8901 
8902    Logically Collective on Mat
8903 
8904    Input Parameters:
8905 +  F - the factored matrix obtained by calling MatGetFactor()
8906 .  *S - location where to return the Schur complement, can be NULL
8907 -  status - the status of the Schur complement matrix, can be NULL
8908 
8909    Notes:
8910    You must call MatFactorSetSchurIS() before calling this routine.
8911 
8912    Schur complement mode is currently implemented for sequential matrices.
8913    The routine returns a the Schur Complement stored within the data strutures of the solver.
8914    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8915    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8916 
8917    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8918 
8919    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8920 
8921    Level: advanced
8922 
8923    References:
8924 
8925 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8926 @*/
8927 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8928 {
8929   PetscFunctionBegin;
8930   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8931   if (S) PetscValidPointer(S,2);
8932   if (status) PetscValidPointer(status,3);
8933   if (S) *S = F->schur;
8934   if (status) *status = F->schur_status;
8935   PetscFunctionReturn(0);
8936 }
8937 
8938 /*@
8939   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8940 
8941    Logically Collective on Mat
8942 
8943    Input Parameters:
8944 +  F - the factored matrix obtained by calling MatGetFactor()
8945 .  *S - location where the Schur complement is stored
8946 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8947 
8948    Notes:
8949 
8950    Level: advanced
8951 
8952    References:
8953 
8954 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8955 @*/
8956 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8957 {
8958   PetscErrorCode ierr;
8959 
8960   PetscFunctionBegin;
8961   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8962   if (S) {
8963     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8964     *S = NULL;
8965   }
8966   F->schur_status = status;
8967   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8968   PetscFunctionReturn(0);
8969 }
8970 
8971 /*@
8972   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8973 
8974    Logically Collective on Mat
8975 
8976    Input Parameters:
8977 +  F - the factored matrix obtained by calling MatGetFactor()
8978 .  rhs - location where the right hand side of the Schur complement system is stored
8979 -  sol - location where the solution of the Schur complement system has to be returned
8980 
8981    Notes:
8982    The sizes of the vectors should match the size of the Schur complement
8983 
8984    Must be called after MatFactorSetSchurIS()
8985 
8986    Level: advanced
8987 
8988    References:
8989 
8990 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8991 @*/
8992 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8993 {
8994   PetscErrorCode ierr;
8995 
8996   PetscFunctionBegin;
8997   PetscValidType(F,1);
8998   PetscValidType(rhs,2);
8999   PetscValidType(sol,3);
9000   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9001   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9002   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9003   PetscCheckSameComm(F,1,rhs,2);
9004   PetscCheckSameComm(F,1,sol,3);
9005   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9006   switch (F->schur_status) {
9007   case MAT_FACTOR_SCHUR_FACTORED:
9008     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9009     break;
9010   case MAT_FACTOR_SCHUR_INVERTED:
9011     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9012     break;
9013   default:
9014     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9015     break;
9016   }
9017   PetscFunctionReturn(0);
9018 }
9019 
9020 /*@
9021   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9022 
9023    Logically Collective on Mat
9024 
9025    Input Parameters:
9026 +  F - the factored matrix obtained by calling MatGetFactor()
9027 .  rhs - location where the right hand side of the Schur complement system is stored
9028 -  sol - location where the solution of the Schur complement system has to be returned
9029 
9030    Notes:
9031    The sizes of the vectors should match the size of the Schur complement
9032 
9033    Must be called after MatFactorSetSchurIS()
9034 
9035    Level: advanced
9036 
9037    References:
9038 
9039 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9040 @*/
9041 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9042 {
9043   PetscErrorCode ierr;
9044 
9045   PetscFunctionBegin;
9046   PetscValidType(F,1);
9047   PetscValidType(rhs,2);
9048   PetscValidType(sol,3);
9049   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9050   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9051   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9052   PetscCheckSameComm(F,1,rhs,2);
9053   PetscCheckSameComm(F,1,sol,3);
9054   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9055   switch (F->schur_status) {
9056   case MAT_FACTOR_SCHUR_FACTORED:
9057     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9058     break;
9059   case MAT_FACTOR_SCHUR_INVERTED:
9060     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9061     break;
9062   default:
9063     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9064     break;
9065   }
9066   PetscFunctionReturn(0);
9067 }
9068 
9069 /*@
9070   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9071 
9072    Logically Collective on Mat
9073 
9074    Input Parameters:
9075 .  F - the factored matrix obtained by calling MatGetFactor()
9076 
9077    Notes:
9078     Must be called after MatFactorSetSchurIS().
9079 
9080    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9081 
9082    Level: advanced
9083 
9084    References:
9085 
9086 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9087 @*/
9088 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9089 {
9090   PetscErrorCode ierr;
9091 
9092   PetscFunctionBegin;
9093   PetscValidType(F,1);
9094   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9095   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9096   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9097   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9098   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9099   PetscFunctionReturn(0);
9100 }
9101 
9102 /*@
9103   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9104 
9105    Logically Collective on Mat
9106 
9107    Input Parameters:
9108 .  F - the factored matrix obtained by calling MatGetFactor()
9109 
9110    Notes:
9111     Must be called after MatFactorSetSchurIS().
9112 
9113    Level: advanced
9114 
9115    References:
9116 
9117 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9118 @*/
9119 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9120 {
9121   PetscErrorCode ierr;
9122 
9123   PetscFunctionBegin;
9124   PetscValidType(F,1);
9125   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9126   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9127   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9128   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9129   PetscFunctionReturn(0);
9130 }
9131 
9132 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9133 {
9134   Mat            AP;
9135   PetscErrorCode ierr;
9136 
9137   PetscFunctionBegin;
9138   ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr);
9139   ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr);
9140   ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr);
9141   ierr = MatDestroy(&AP);CHKERRQ(ierr);
9142   PetscFunctionReturn(0);
9143 }
9144 
9145 /*@
9146    MatPtAP - Creates the matrix product C = P^T * A * P
9147 
9148    Neighbor-wise Collective on Mat
9149 
9150    Input Parameters:
9151 +  A - the matrix
9152 .  P - the projection matrix
9153 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9154 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9155           if the result is a dense matrix this is irrelevent
9156 
9157    Output Parameters:
9158 .  C - the product matrix
9159 
9160    Notes:
9161    C will be created and must be destroyed by the user with MatDestroy().
9162 
9163    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9164 
9165    Level: intermediate
9166 
9167 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9168 @*/
9169 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9170 {
9171   PetscErrorCode ierr;
9172   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9173   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9174   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9175   PetscBool      sametype;
9176 
9177   PetscFunctionBegin;
9178   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9179   PetscValidType(A,1);
9180   MatCheckPreallocated(A,1);
9181   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9182   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9184   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9185   PetscValidType(P,2);
9186   MatCheckPreallocated(P,2);
9187   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9188   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9189 
9190   if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N);
9191   if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9192   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9193   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9194 
9195   if (scall == MAT_REUSE_MATRIX) {
9196     PetscValidPointer(*C,5);
9197     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9198 
9199     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9200     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9201     if ((*C)->ops->ptapnumeric) {
9202       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9203     } else {
9204       ierr = MatPtAP_Basic(A,P,scall,fill,C);
9205     }
9206     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9207     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9208     PetscFunctionReturn(0);
9209   }
9210 
9211   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9212   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9213 
9214   fA = A->ops->ptap;
9215   fP = P->ops->ptap;
9216   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9217   if (fP == fA && sametype) {
9218     ptap = fA;
9219   } else {
9220     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9221     char ptapname[256];
9222     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9223     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9224     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9225     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9226     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9227     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9228   }
9229 
9230   if (!ptap) ptap = MatPtAP_Basic;
9231   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9232   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9233   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9234   if (A->symmetric_set && A->symmetric) {
9235     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9236   }
9237   PetscFunctionReturn(0);
9238 }
9239 
9240 /*@
9241    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9242 
9243    Neighbor-wise Collective on Mat
9244 
9245    Input Parameters:
9246 +  A - the matrix
9247 -  P - the projection matrix
9248 
9249    Output Parameters:
9250 .  C - the product matrix
9251 
9252    Notes:
9253    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9254    the user using MatDeatroy().
9255 
9256    This routine is currently only implemented for pairs of AIJ matrices and classes
9257    which inherit from AIJ.  C will be of type MATAIJ.
9258 
9259    Level: intermediate
9260 
9261 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9262 @*/
9263 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9264 {
9265   PetscErrorCode ierr;
9266 
9267   PetscFunctionBegin;
9268   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9269   PetscValidType(A,1);
9270   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9271   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9272   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9273   PetscValidType(P,2);
9274   MatCheckPreallocated(P,2);
9275   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9276   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9277   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9278   PetscValidType(C,3);
9279   MatCheckPreallocated(C,3);
9280   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9281   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
9282   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9283   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9284   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
9285   MatCheckPreallocated(A,1);
9286 
9287   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9288   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9289   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9290   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9291   PetscFunctionReturn(0);
9292 }
9293 
9294 /*@
9295    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9296 
9297    Neighbor-wise Collective on Mat
9298 
9299    Input Parameters:
9300 +  A - the matrix
9301 -  P - the projection matrix
9302 
9303    Output Parameters:
9304 .  C - the (i,j) structure of the product matrix
9305 
9306    Notes:
9307    C will be created and must be destroyed by the user with MatDestroy().
9308 
9309    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9310    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9311    this (i,j) structure by calling MatPtAPNumeric().
9312 
9313    Level: intermediate
9314 
9315 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9316 @*/
9317 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9318 {
9319   PetscErrorCode ierr;
9320 
9321   PetscFunctionBegin;
9322   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9323   PetscValidType(A,1);
9324   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9325   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9326   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9327   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9328   PetscValidType(P,2);
9329   MatCheckPreallocated(P,2);
9330   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9331   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9332   PetscValidPointer(C,3);
9333 
9334   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9335   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9336   MatCheckPreallocated(A,1);
9337 
9338   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9339   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9340   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9341   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9342 
9343   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9344   PetscFunctionReturn(0);
9345 }
9346 
9347 /*@
9348    MatRARt - Creates the matrix product C = R * A * R^T
9349 
9350    Neighbor-wise Collective on Mat
9351 
9352    Input Parameters:
9353 +  A - the matrix
9354 .  R - the projection matrix
9355 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9356 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9357           if the result is a dense matrix this is irrelevent
9358 
9359    Output Parameters:
9360 .  C - the product matrix
9361 
9362    Notes:
9363    C will be created and must be destroyed by the user with MatDestroy().
9364 
9365    This routine is currently only implemented for pairs of AIJ matrices and classes
9366    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9367    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9368    We recommend using MatPtAP().
9369 
9370    Level: intermediate
9371 
9372 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9373 @*/
9374 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9375 {
9376   PetscErrorCode ierr;
9377 
9378   PetscFunctionBegin;
9379   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9380   PetscValidType(A,1);
9381   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9382   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9383   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9384   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9385   PetscValidType(R,2);
9386   MatCheckPreallocated(R,2);
9387   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9388   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9389   PetscValidPointer(C,3);
9390   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9391 
9392   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9393   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9394   MatCheckPreallocated(A,1);
9395 
9396   if (!A->ops->rart) {
9397     Mat Rt;
9398     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9399     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9400     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9401     PetscFunctionReturn(0);
9402   }
9403   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9404   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9405   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9406   PetscFunctionReturn(0);
9407 }
9408 
9409 /*@
9410    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9411 
9412    Neighbor-wise Collective on Mat
9413 
9414    Input Parameters:
9415 +  A - the matrix
9416 -  R - the projection matrix
9417 
9418    Output Parameters:
9419 .  C - the product matrix
9420 
9421    Notes:
9422    C must have been created by calling MatRARtSymbolic and must be destroyed by
9423    the user using MatDestroy().
9424 
9425    This routine is currently only implemented for pairs of AIJ matrices and classes
9426    which inherit from AIJ.  C will be of type MATAIJ.
9427 
9428    Level: intermediate
9429 
9430 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9431 @*/
9432 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9433 {
9434   PetscErrorCode ierr;
9435 
9436   PetscFunctionBegin;
9437   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9438   PetscValidType(A,1);
9439   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9440   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9441   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9442   PetscValidType(R,2);
9443   MatCheckPreallocated(R,2);
9444   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9445   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9446   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9447   PetscValidType(C,3);
9448   MatCheckPreallocated(C,3);
9449   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9450   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9451   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9452   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9453   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9454   MatCheckPreallocated(A,1);
9455 
9456   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9457   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9458   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9459   PetscFunctionReturn(0);
9460 }
9461 
9462 /*@
9463    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9464 
9465    Neighbor-wise Collective on Mat
9466 
9467    Input Parameters:
9468 +  A - the matrix
9469 -  R - the projection matrix
9470 
9471    Output Parameters:
9472 .  C - the (i,j) structure of the product matrix
9473 
9474    Notes:
9475    C will be created and must be destroyed by the user with MatDestroy().
9476 
9477    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9478    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9479    this (i,j) structure by calling MatRARtNumeric().
9480 
9481    Level: intermediate
9482 
9483 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9484 @*/
9485 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9486 {
9487   PetscErrorCode ierr;
9488 
9489   PetscFunctionBegin;
9490   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9491   PetscValidType(A,1);
9492   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9493   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9494   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9495   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9496   PetscValidType(R,2);
9497   MatCheckPreallocated(R,2);
9498   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9499   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9500   PetscValidPointer(C,3);
9501 
9502   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9503   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9504   MatCheckPreallocated(A,1);
9505   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9506   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9507   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9508 
9509   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9510   PetscFunctionReturn(0);
9511 }
9512 
9513 /*@
9514    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9515 
9516    Neighbor-wise Collective on Mat
9517 
9518    Input Parameters:
9519 +  A - the left matrix
9520 .  B - the right matrix
9521 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9522 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9523           if the result is a dense matrix this is irrelevent
9524 
9525    Output Parameters:
9526 .  C - the product matrix
9527 
9528    Notes:
9529    Unless scall is MAT_REUSE_MATRIX C will be created.
9530 
9531    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
9532    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9533 
9534    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9535    actually needed.
9536 
9537    If you have many matrices with the same non-zero structure to multiply, you
9538    should either
9539 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9540 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9541    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
9542    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9543 
9544    Level: intermediate
9545 
9546 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9547 @*/
9548 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9549 {
9550   PetscErrorCode ierr;
9551   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9552   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9553   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9554   Mat            T;
9555   PetscBool      istrans;
9556 
9557   PetscFunctionBegin;
9558   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9559   PetscValidType(A,1);
9560   MatCheckPreallocated(A,1);
9561   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9562   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9563   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9564   PetscValidType(B,2);
9565   MatCheckPreallocated(B,2);
9566   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9567   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9568   PetscValidPointer(C,3);
9569   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9570   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9571   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9572   if (istrans) {
9573     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9574     ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9575     PetscFunctionReturn(0);
9576   } else {
9577     ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9578     if (istrans) {
9579       ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9580       ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr);
9581       PetscFunctionReturn(0);
9582     }
9583   }
9584   if (scall == MAT_REUSE_MATRIX) {
9585     PetscValidPointer(*C,5);
9586     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9587     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9588     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9589     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9590     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9591     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9592     PetscFunctionReturn(0);
9593   }
9594   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9595   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9596 
9597   fA = A->ops->matmult;
9598   fB = B->ops->matmult;
9599   if (fB == fA) {
9600     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9601     mult = fB;
9602   } else {
9603     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9604     char multname[256];
9605     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9606     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9607     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9608     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9609     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9610     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9611     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9612   }
9613   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9614   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9615   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9616   PetscFunctionReturn(0);
9617 }
9618 
9619 /*@
9620    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9621    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9622 
9623    Neighbor-wise Collective on Mat
9624 
9625    Input Parameters:
9626 +  A - the left matrix
9627 .  B - the right matrix
9628 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9629       if C is a dense matrix this is irrelevent
9630 
9631    Output Parameters:
9632 .  C - the product matrix
9633 
9634    Notes:
9635    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9636    actually needed.
9637 
9638    This routine is currently implemented for
9639     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9640     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9641     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9642 
9643    Level: intermediate
9644 
9645    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9646      We should incorporate them into PETSc.
9647 
9648 .seealso: MatMatMult(), MatMatMultNumeric()
9649 @*/
9650 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9651 {
9652   PetscErrorCode ierr;
9653   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9654   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9655   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9656 
9657   PetscFunctionBegin;
9658   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9659   PetscValidType(A,1);
9660   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9661   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9662 
9663   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9664   PetscValidType(B,2);
9665   MatCheckPreallocated(B,2);
9666   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9667   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9668   PetscValidPointer(C,3);
9669 
9670   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9671   if (fill == PETSC_DEFAULT) fill = 2.0;
9672   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9673   MatCheckPreallocated(A,1);
9674 
9675   Asymbolic = A->ops->matmultsymbolic;
9676   Bsymbolic = B->ops->matmultsymbolic;
9677   if (Asymbolic == Bsymbolic) {
9678     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9679     symbolic = Bsymbolic;
9680   } else { /* dispatch based on the type of A and B */
9681     char symbolicname[256];
9682     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9683     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9684     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9685     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9686     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9687     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9688     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9689   }
9690   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9691   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9692   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9693   PetscFunctionReturn(0);
9694 }
9695 
9696 /*@
9697    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9698    Call this routine after first calling MatMatMultSymbolic().
9699 
9700    Neighbor-wise Collective on Mat
9701 
9702    Input Parameters:
9703 +  A - the left matrix
9704 -  B - the right matrix
9705 
9706    Output Parameters:
9707 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9708 
9709    Notes:
9710    C must have been created with MatMatMultSymbolic().
9711 
9712    This routine is currently implemented for
9713     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9714     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9715     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9716 
9717    Level: intermediate
9718 
9719 .seealso: MatMatMult(), MatMatMultSymbolic()
9720 @*/
9721 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9722 {
9723   PetscErrorCode ierr;
9724 
9725   PetscFunctionBegin;
9726   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9727   PetscFunctionReturn(0);
9728 }
9729 
9730 /*@
9731    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9732 
9733    Neighbor-wise Collective on Mat
9734 
9735    Input Parameters:
9736 +  A - the left matrix
9737 .  B - the right matrix
9738 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9739 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9740 
9741    Output Parameters:
9742 .  C - the product matrix
9743 
9744    Notes:
9745    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9746 
9747    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9748 
9749   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9750    actually needed.
9751 
9752    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9753    and for pairs of MPIDense matrices.
9754 
9755    Options Database Keys:
9756 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9757                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9758                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9759 
9760    Level: intermediate
9761 
9762 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9763 @*/
9764 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9765 {
9766   PetscErrorCode ierr;
9767   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9768   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9769   Mat            T;
9770   PetscBool      istrans;
9771 
9772   PetscFunctionBegin;
9773   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9774   PetscValidType(A,1);
9775   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9776   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9777   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9778   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9779   PetscValidType(B,2);
9780   MatCheckPreallocated(B,2);
9781   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9782   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9783   PetscValidPointer(C,3);
9784   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9785   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9786   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9787   MatCheckPreallocated(A,1);
9788 
9789   ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9790   if (istrans) {
9791     ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9792     ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr);
9793     PetscFunctionReturn(0);
9794   }
9795   fA = A->ops->mattransposemult;
9796   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9797   fB = B->ops->mattransposemult;
9798   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9799   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9800 
9801   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9802   if (scall == MAT_INITIAL_MATRIX) {
9803     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9804     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9805     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9806   }
9807   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9808   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9809   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9810   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9811   PetscFunctionReturn(0);
9812 }
9813 
9814 /*@
9815    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9816 
9817    Neighbor-wise Collective on Mat
9818 
9819    Input Parameters:
9820 +  A - the left matrix
9821 .  B - the right matrix
9822 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9823 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9824 
9825    Output Parameters:
9826 .  C - the product matrix
9827 
9828    Notes:
9829    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9830 
9831    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9832 
9833   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9834    actually needed.
9835 
9836    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9837    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9838 
9839    Level: intermediate
9840 
9841 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9842 @*/
9843 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9844 {
9845   PetscErrorCode ierr;
9846   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9847   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9848   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9849   Mat            T;
9850   PetscBool      istrans;
9851 
9852   PetscFunctionBegin;
9853   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9854   PetscValidType(A,1);
9855   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9856   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9857   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9858   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9859   PetscValidType(B,2);
9860   MatCheckPreallocated(B,2);
9861   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9862   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9863   PetscValidPointer(C,3);
9864   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9865   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9866   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9867   MatCheckPreallocated(A,1);
9868 
9869   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9870   if (istrans) {
9871     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9872     ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9873     PetscFunctionReturn(0);
9874   }
9875   fA = A->ops->transposematmult;
9876   fB = B->ops->transposematmult;
9877   if (fB==fA) {
9878     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9879     transposematmult = fA;
9880   } else {
9881     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9882     char multname[256];
9883     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9884     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9885     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9886     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9887     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9888     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9889     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9890   }
9891   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9892   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9893   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9894   PetscFunctionReturn(0);
9895 }
9896 
9897 /*@
9898    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9899 
9900    Neighbor-wise Collective on Mat
9901 
9902    Input Parameters:
9903 +  A - the left matrix
9904 .  B - the middle matrix
9905 .  C - the right matrix
9906 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9907 -  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
9908           if the result is a dense matrix this is irrelevent
9909 
9910    Output Parameters:
9911 .  D - the product matrix
9912 
9913    Notes:
9914    Unless scall is MAT_REUSE_MATRIX D will be created.
9915 
9916    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9917 
9918    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9919    actually needed.
9920 
9921    If you have many matrices with the same non-zero structure to multiply, you
9922    should use MAT_REUSE_MATRIX in all calls but the first or
9923 
9924    Level: intermediate
9925 
9926 .seealso: MatMatMult, MatPtAP()
9927 @*/
9928 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9929 {
9930   PetscErrorCode ierr;
9931   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9932   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9933   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9934   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9935 
9936   PetscFunctionBegin;
9937   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9938   PetscValidType(A,1);
9939   MatCheckPreallocated(A,1);
9940   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9941   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9942   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9943   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9944   PetscValidType(B,2);
9945   MatCheckPreallocated(B,2);
9946   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9947   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9948   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9949   PetscValidPointer(C,3);
9950   MatCheckPreallocated(C,3);
9951   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9952   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9953   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9954   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9955   if (scall == MAT_REUSE_MATRIX) {
9956     PetscValidPointer(*D,6);
9957     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9958     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9959     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9960     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9961     PetscFunctionReturn(0);
9962   }
9963   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9964   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9965 
9966   fA = A->ops->matmatmult;
9967   fB = B->ops->matmatmult;
9968   fC = C->ops->matmatmult;
9969   if (fA == fB && fA == fC) {
9970     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9971     mult = fA;
9972   } else {
9973     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9974     char multname[256];
9975     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9976     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9977     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9978     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9979     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9980     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9981     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9982     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9983     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9984   }
9985   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9986   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9987   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9988   PetscFunctionReturn(0);
9989 }
9990 
9991 /*@
9992    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9993 
9994    Collective on Mat
9995 
9996    Input Parameters:
9997 +  mat - the matrix
9998 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9999 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10000 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10001 
10002    Output Parameter:
10003 .  matredundant - redundant matrix
10004 
10005    Notes:
10006    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10007    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10008 
10009    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10010    calling it.
10011 
10012    Level: advanced
10013 
10014 
10015 .seealso: MatDestroy()
10016 @*/
10017 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10018 {
10019   PetscErrorCode ierr;
10020   MPI_Comm       comm;
10021   PetscMPIInt    size;
10022   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10023   Mat_Redundant  *redund=NULL;
10024   PetscSubcomm   psubcomm=NULL;
10025   MPI_Comm       subcomm_in=subcomm;
10026   Mat            *matseq;
10027   IS             isrow,iscol;
10028   PetscBool      newsubcomm=PETSC_FALSE;
10029 
10030   PetscFunctionBegin;
10031   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10032   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10033     PetscValidPointer(*matredundant,5);
10034     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10035   }
10036 
10037   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10038   if (size == 1 || nsubcomm == 1) {
10039     if (reuse == MAT_INITIAL_MATRIX) {
10040       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10041     } else {
10042       if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10043       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10044     }
10045     PetscFunctionReturn(0);
10046   }
10047 
10048   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10049   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10050   MatCheckPreallocated(mat,1);
10051 
10052   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10053   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10054     /* create psubcomm, then get subcomm */
10055     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10056     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10057     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10058 
10059     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10060     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10061     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10062     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10063     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10064     newsubcomm = PETSC_TRUE;
10065     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10066   }
10067 
10068   /* get isrow, iscol and a local sequential matrix matseq[0] */
10069   if (reuse == MAT_INITIAL_MATRIX) {
10070     mloc_sub = PETSC_DECIDE;
10071     nloc_sub = PETSC_DECIDE;
10072     if (bs < 1) {
10073       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10074       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10075     } else {
10076       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10077       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10078     }
10079     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10080     rstart = rend - mloc_sub;
10081     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10082     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10083   } else { /* reuse == MAT_REUSE_MATRIX */
10084     if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10085     /* retrieve subcomm */
10086     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10087     redund = (*matredundant)->redundant;
10088     isrow  = redund->isrow;
10089     iscol  = redund->iscol;
10090     matseq = redund->matseq;
10091   }
10092   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10093 
10094   /* get matredundant over subcomm */
10095   if (reuse == MAT_INITIAL_MATRIX) {
10096     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10097 
10098     /* create a supporting struct and attach it to C for reuse */
10099     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10100     (*matredundant)->redundant = redund;
10101     redund->isrow              = isrow;
10102     redund->iscol              = iscol;
10103     redund->matseq             = matseq;
10104     if (newsubcomm) {
10105       redund->subcomm          = subcomm;
10106     } else {
10107       redund->subcomm          = MPI_COMM_NULL;
10108     }
10109   } else {
10110     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10111   }
10112   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10113   PetscFunctionReturn(0);
10114 }
10115 
10116 /*@C
10117    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10118    a given 'mat' object. Each submatrix can span multiple procs.
10119 
10120    Collective on Mat
10121 
10122    Input Parameters:
10123 +  mat - the matrix
10124 .  subcomm - the subcommunicator obtained by com_split(comm)
10125 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10126 
10127    Output Parameter:
10128 .  subMat - 'parallel submatrices each spans a given subcomm
10129 
10130   Notes:
10131   The submatrix partition across processors is dictated by 'subComm' a
10132   communicator obtained by com_split(comm). The comm_split
10133   is not restriced to be grouped with consecutive original ranks.
10134 
10135   Due the comm_split() usage, the parallel layout of the submatrices
10136   map directly to the layout of the original matrix [wrt the local
10137   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10138   into the 'DiagonalMat' of the subMat, hence it is used directly from
10139   the subMat. However the offDiagMat looses some columns - and this is
10140   reconstructed with MatSetValues()
10141 
10142   Level: advanced
10143 
10144 
10145 .seealso: MatCreateSubMatrices()
10146 @*/
10147 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10148 {
10149   PetscErrorCode ierr;
10150   PetscMPIInt    commsize,subCommSize;
10151 
10152   PetscFunctionBegin;
10153   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10154   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10155   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10156 
10157   if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10158   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10159   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10160   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10161   PetscFunctionReturn(0);
10162 }
10163 
10164 /*@
10165    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10166 
10167    Not Collective
10168 
10169    Input Arguments:
10170    mat - matrix to extract local submatrix from
10171    isrow - local row indices for submatrix
10172    iscol - local column indices for submatrix
10173 
10174    Output Arguments:
10175    submat - the submatrix
10176 
10177    Level: intermediate
10178 
10179    Notes:
10180    The submat should be returned with MatRestoreLocalSubMatrix().
10181 
10182    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10183    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10184 
10185    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10186    MatSetValuesBlockedLocal() will also be implemented.
10187 
10188    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10189    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10190 
10191 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10192 @*/
10193 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10194 {
10195   PetscErrorCode ierr;
10196 
10197   PetscFunctionBegin;
10198   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10199   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10200   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10201   PetscCheckSameComm(isrow,2,iscol,3);
10202   PetscValidPointer(submat,4);
10203   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10204 
10205   if (mat->ops->getlocalsubmatrix) {
10206     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10207   } else {
10208     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10209   }
10210   PetscFunctionReturn(0);
10211 }
10212 
10213 /*@
10214    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10215 
10216    Not Collective
10217 
10218    Input Arguments:
10219    mat - matrix to extract local submatrix from
10220    isrow - local row indices for submatrix
10221    iscol - local column indices for submatrix
10222    submat - the submatrix
10223 
10224    Level: intermediate
10225 
10226 .seealso: MatGetLocalSubMatrix()
10227 @*/
10228 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10229 {
10230   PetscErrorCode ierr;
10231 
10232   PetscFunctionBegin;
10233   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10234   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10235   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10236   PetscCheckSameComm(isrow,2,iscol,3);
10237   PetscValidPointer(submat,4);
10238   if (*submat) {
10239     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10240   }
10241 
10242   if (mat->ops->restorelocalsubmatrix) {
10243     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10244   } else {
10245     ierr = MatDestroy(submat);CHKERRQ(ierr);
10246   }
10247   *submat = NULL;
10248   PetscFunctionReturn(0);
10249 }
10250 
10251 /* --------------------------------------------------------*/
10252 /*@
10253    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10254 
10255    Collective on Mat
10256 
10257    Input Parameter:
10258 .  mat - the matrix
10259 
10260    Output Parameter:
10261 .  is - if any rows have zero diagonals this contains the list of them
10262 
10263    Level: developer
10264 
10265 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10266 @*/
10267 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10268 {
10269   PetscErrorCode ierr;
10270 
10271   PetscFunctionBegin;
10272   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10273   PetscValidType(mat,1);
10274   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10275   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10276 
10277   if (!mat->ops->findzerodiagonals) {
10278     Vec                diag;
10279     const PetscScalar *a;
10280     PetscInt          *rows;
10281     PetscInt           rStart, rEnd, r, nrow = 0;
10282 
10283     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10284     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10285     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10286     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10287     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10288     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10289     nrow = 0;
10290     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10291     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10292     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10293     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10294   } else {
10295     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10296   }
10297   PetscFunctionReturn(0);
10298 }
10299 
10300 /*@
10301    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10302 
10303    Collective on Mat
10304 
10305    Input Parameter:
10306 .  mat - the matrix
10307 
10308    Output Parameter:
10309 .  is - contains the list of rows with off block diagonal entries
10310 
10311    Level: developer
10312 
10313 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10314 @*/
10315 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10316 {
10317   PetscErrorCode ierr;
10318 
10319   PetscFunctionBegin;
10320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10321   PetscValidType(mat,1);
10322   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10323   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10324 
10325   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10326   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10327   PetscFunctionReturn(0);
10328 }
10329 
10330 /*@C
10331   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10332 
10333   Collective on Mat
10334 
10335   Input Parameters:
10336 . mat - the matrix
10337 
10338   Output Parameters:
10339 . values - the block inverses in column major order (FORTRAN-like)
10340 
10341    Note:
10342    This routine is not available from Fortran.
10343 
10344   Level: advanced
10345 
10346 .seealso: MatInvertBockDiagonalMat
10347 @*/
10348 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10349 {
10350   PetscErrorCode ierr;
10351 
10352   PetscFunctionBegin;
10353   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10354   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10355   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10356   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10357   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10358   PetscFunctionReturn(0);
10359 }
10360 
10361 /*@C
10362   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10363 
10364   Collective on Mat
10365 
10366   Input Parameters:
10367 + mat - the matrix
10368 . nblocks - the number of blocks
10369 - bsizes - the size of each block
10370 
10371   Output Parameters:
10372 . values - the block inverses in column major order (FORTRAN-like)
10373 
10374    Note:
10375    This routine is not available from Fortran.
10376 
10377   Level: advanced
10378 
10379 .seealso: MatInvertBockDiagonal()
10380 @*/
10381 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10382 {
10383   PetscErrorCode ierr;
10384 
10385   PetscFunctionBegin;
10386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10387   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10388   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10389   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10390   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10391   PetscFunctionReturn(0);
10392 }
10393 
10394 /*@
10395   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10396 
10397   Collective on Mat
10398 
10399   Input Parameters:
10400 . A - the matrix
10401 
10402   Output Parameters:
10403 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10404 
10405   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10406 
10407   Level: advanced
10408 
10409 .seealso: MatInvertBockDiagonal()
10410 @*/
10411 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10412 {
10413   PetscErrorCode     ierr;
10414   const PetscScalar *vals;
10415   PetscInt          *dnnz;
10416   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10417 
10418   PetscFunctionBegin;
10419   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10420   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10421   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10422   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10423   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10424   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10425   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10426   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10427   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10428   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10429   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10430   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10431   for (i = rstart/bs; i < rend/bs; i++) {
10432     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10433   }
10434   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10435   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10436   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10437   PetscFunctionReturn(0);
10438 }
10439 
10440 /*@C
10441     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10442     via MatTransposeColoringCreate().
10443 
10444     Collective on MatTransposeColoring
10445 
10446     Input Parameter:
10447 .   c - coloring context
10448 
10449     Level: intermediate
10450 
10451 .seealso: MatTransposeColoringCreate()
10452 @*/
10453 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10454 {
10455   PetscErrorCode       ierr;
10456   MatTransposeColoring matcolor=*c;
10457 
10458   PetscFunctionBegin;
10459   if (!matcolor) PetscFunctionReturn(0);
10460   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10461 
10462   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10463   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10464   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10465   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10466   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10467   if (matcolor->brows>0) {
10468     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10469   }
10470   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10471   PetscFunctionReturn(0);
10472 }
10473 
10474 /*@C
10475     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10476     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10477     MatTransposeColoring to sparse B.
10478 
10479     Collective on MatTransposeColoring
10480 
10481     Input Parameters:
10482 +   B - sparse matrix B
10483 .   Btdense - symbolic dense matrix B^T
10484 -   coloring - coloring context created with MatTransposeColoringCreate()
10485 
10486     Output Parameter:
10487 .   Btdense - dense matrix B^T
10488 
10489     Level: advanced
10490 
10491      Notes:
10492     These are used internally for some implementations of MatRARt()
10493 
10494 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10495 
10496 @*/
10497 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10498 {
10499   PetscErrorCode ierr;
10500 
10501   PetscFunctionBegin;
10502   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10503   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10504   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10505 
10506   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10507   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10508   PetscFunctionReturn(0);
10509 }
10510 
10511 /*@C
10512     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10513     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10514     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10515     Csp from Cden.
10516 
10517     Collective on MatTransposeColoring
10518 
10519     Input Parameters:
10520 +   coloring - coloring context created with MatTransposeColoringCreate()
10521 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10522 
10523     Output Parameter:
10524 .   Csp - sparse matrix
10525 
10526     Level: advanced
10527 
10528      Notes:
10529     These are used internally for some implementations of MatRARt()
10530 
10531 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10532 
10533 @*/
10534 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10535 {
10536   PetscErrorCode ierr;
10537 
10538   PetscFunctionBegin;
10539   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10540   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10541   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10542 
10543   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10544   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10545   PetscFunctionReturn(0);
10546 }
10547 
10548 /*@C
10549    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10550 
10551    Collective on Mat
10552 
10553    Input Parameters:
10554 +  mat - the matrix product C
10555 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10556 
10557     Output Parameter:
10558 .   color - the new coloring context
10559 
10560     Level: intermediate
10561 
10562 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10563            MatTransColoringApplyDenToSp()
10564 @*/
10565 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10566 {
10567   MatTransposeColoring c;
10568   MPI_Comm             comm;
10569   PetscErrorCode       ierr;
10570 
10571   PetscFunctionBegin;
10572   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10573   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10574   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10575 
10576   c->ctype = iscoloring->ctype;
10577   if (mat->ops->transposecoloringcreate) {
10578     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10579   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10580 
10581   *color = c;
10582   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10583   PetscFunctionReturn(0);
10584 }
10585 
10586 /*@
10587       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10588         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10589         same, otherwise it will be larger
10590 
10591      Not Collective
10592 
10593   Input Parameter:
10594 .    A  - the matrix
10595 
10596   Output Parameter:
10597 .    state - the current state
10598 
10599   Notes:
10600     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10601          different matrices
10602 
10603   Level: intermediate
10604 
10605 @*/
10606 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10607 {
10608   PetscFunctionBegin;
10609   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10610   *state = mat->nonzerostate;
10611   PetscFunctionReturn(0);
10612 }
10613 
10614 /*@
10615       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10616                  matrices from each processor
10617 
10618     Collective
10619 
10620    Input Parameters:
10621 +    comm - the communicators the parallel matrix will live on
10622 .    seqmat - the input sequential matrices
10623 .    n - number of local columns (or PETSC_DECIDE)
10624 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10625 
10626    Output Parameter:
10627 .    mpimat - the parallel matrix generated
10628 
10629     Level: advanced
10630 
10631    Notes:
10632     The number of columns of the matrix in EACH processor MUST be the same.
10633 
10634 @*/
10635 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10636 {
10637   PetscErrorCode ierr;
10638 
10639   PetscFunctionBegin;
10640   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10641   if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10642 
10643   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10644   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10645   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10646   PetscFunctionReturn(0);
10647 }
10648 
10649 /*@
10650      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10651                  ranks' ownership ranges.
10652 
10653     Collective on A
10654 
10655    Input Parameters:
10656 +    A   - the matrix to create subdomains from
10657 -    N   - requested number of subdomains
10658 
10659 
10660    Output Parameters:
10661 +    n   - number of subdomains resulting on this rank
10662 -    iss - IS list with indices of subdomains on this rank
10663 
10664     Level: advanced
10665 
10666     Notes:
10667     number of subdomains must be smaller than the communicator size
10668 @*/
10669 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10670 {
10671   MPI_Comm        comm,subcomm;
10672   PetscMPIInt     size,rank,color;
10673   PetscInt        rstart,rend,k;
10674   PetscErrorCode  ierr;
10675 
10676   PetscFunctionBegin;
10677   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10678   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10679   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10680   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10681   *n = 1;
10682   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10683   color = rank/k;
10684   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10685   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10686   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10687   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10688   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10689   PetscFunctionReturn(0);
10690 }
10691 
10692 /*@
10693    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10694 
10695    If the interpolation and restriction operators are the same, uses MatPtAP.
10696    If they are not the same, use MatMatMatMult.
10697 
10698    Once the coarse grid problem is constructed, correct for interpolation operators
10699    that are not of full rank, which can legitimately happen in the case of non-nested
10700    geometric multigrid.
10701 
10702    Input Parameters:
10703 +  restrct - restriction operator
10704 .  dA - fine grid matrix
10705 .  interpolate - interpolation operator
10706 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10707 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10708 
10709    Output Parameters:
10710 .  A - the Galerkin coarse matrix
10711 
10712    Options Database Key:
10713 .  -pc_mg_galerkin <both,pmat,mat,none>
10714 
10715    Level: developer
10716 
10717 .seealso: MatPtAP(), MatMatMatMult()
10718 @*/
10719 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10720 {
10721   PetscErrorCode ierr;
10722   IS             zerorows;
10723   Vec            diag;
10724 
10725   PetscFunctionBegin;
10726   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10727   /* Construct the coarse grid matrix */
10728   if (interpolate == restrct) {
10729     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10730   } else {
10731     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10732   }
10733 
10734   /* If the interpolation matrix is not of full rank, A will have zero rows.
10735      This can legitimately happen in the case of non-nested geometric multigrid.
10736      In that event, we set the rows of the matrix to the rows of the identity,
10737      ignoring the equations (as the RHS will also be zero). */
10738 
10739   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10740 
10741   if (zerorows != NULL) { /* if there are any zero rows */
10742     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10743     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10744     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10745     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10746     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10747     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10748   }
10749   PetscFunctionReturn(0);
10750 }
10751 
10752 /*@C
10753     MatSetOperation - Allows user to set a matrix operation for any matrix type
10754 
10755    Logically Collective on Mat
10756 
10757     Input Parameters:
10758 +   mat - the matrix
10759 .   op - the name of the operation
10760 -   f - the function that provides the operation
10761 
10762    Level: developer
10763 
10764     Usage:
10765 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10766 $      ierr = MatCreateXXX(comm,...&A);
10767 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10768 
10769     Notes:
10770     See the file include/petscmat.h for a complete list of matrix
10771     operations, which all have the form MATOP_<OPERATION>, where
10772     <OPERATION> is the name (in all capital letters) of the
10773     user interface routine (e.g., MatMult() -> MATOP_MULT).
10774 
10775     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10776     sequence as the usual matrix interface routines, since they
10777     are intended to be accessed via the usual matrix interface
10778     routines, e.g.,
10779 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10780 
10781     In particular each function MUST return an error code of 0 on success and
10782     nonzero on failure.
10783 
10784     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10785 
10786 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10787 @*/
10788 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10789 {
10790   PetscFunctionBegin;
10791   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10792   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10793     mat->ops->viewnative = mat->ops->view;
10794   }
10795   (((void(**)(void))mat->ops)[op]) = f;
10796   PetscFunctionReturn(0);
10797 }
10798 
10799 /*@C
10800     MatGetOperation - Gets a matrix operation for any matrix type.
10801 
10802     Not Collective
10803 
10804     Input Parameters:
10805 +   mat - the matrix
10806 -   op - the name of the operation
10807 
10808     Output Parameter:
10809 .   f - the function that provides the operation
10810 
10811     Level: developer
10812 
10813     Usage:
10814 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10815 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10816 
10817     Notes:
10818     See the file include/petscmat.h for a complete list of matrix
10819     operations, which all have the form MATOP_<OPERATION>, where
10820     <OPERATION> is the name (in all capital letters) of the
10821     user interface routine (e.g., MatMult() -> MATOP_MULT).
10822 
10823     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10824 
10825 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10826 @*/
10827 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10828 {
10829   PetscFunctionBegin;
10830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10831   *f = (((void (**)(void))mat->ops)[op]);
10832   PetscFunctionReturn(0);
10833 }
10834 
10835 /*@
10836     MatHasOperation - Determines whether the given matrix supports the particular
10837     operation.
10838 
10839    Not Collective
10840 
10841    Input Parameters:
10842 +  mat - the matrix
10843 -  op - the operation, for example, MATOP_GET_DIAGONAL
10844 
10845    Output Parameter:
10846 .  has - either PETSC_TRUE or PETSC_FALSE
10847 
10848    Level: advanced
10849 
10850    Notes:
10851    See the file include/petscmat.h for a complete list of matrix
10852    operations, which all have the form MATOP_<OPERATION>, where
10853    <OPERATION> is the name (in all capital letters) of the
10854    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10855 
10856 .seealso: MatCreateShell()
10857 @*/
10858 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10859 {
10860   PetscErrorCode ierr;
10861 
10862   PetscFunctionBegin;
10863   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10864   PetscValidType(mat,1);
10865   PetscValidPointer(has,3);
10866   if (mat->ops->hasoperation) {
10867     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10868   } else {
10869     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10870     else {
10871       *has = PETSC_FALSE;
10872       if (op == MATOP_CREATE_SUBMATRIX) {
10873         PetscMPIInt size;
10874 
10875         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10876         if (size == 1) {
10877           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10878         }
10879       }
10880     }
10881   }
10882   PetscFunctionReturn(0);
10883 }
10884 
10885 /*@
10886     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10887     of the matrix are congruent
10888 
10889    Collective on mat
10890 
10891    Input Parameters:
10892 .  mat - the matrix
10893 
10894    Output Parameter:
10895 .  cong - either PETSC_TRUE or PETSC_FALSE
10896 
10897    Level: beginner
10898 
10899    Notes:
10900 
10901 .seealso: MatCreate(), MatSetSizes()
10902 @*/
10903 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10904 {
10905   PetscErrorCode ierr;
10906 
10907   PetscFunctionBegin;
10908   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10909   PetscValidType(mat,1);
10910   PetscValidPointer(cong,2);
10911   if (!mat->rmap || !mat->cmap) {
10912     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10913     PetscFunctionReturn(0);
10914   }
10915   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10916     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10917     if (*cong) mat->congruentlayouts = 1;
10918     else       mat->congruentlayouts = 0;
10919   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10920   PetscFunctionReturn(0);
10921 }
10922 
10923 /*@
10924     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
10925     e.g., matrx product of MatPtAP.
10926 
10927    Collective on mat
10928 
10929    Input Parameters:
10930 .  mat - the matrix
10931 
10932    Output Parameter:
10933 .  mat - the matrix with intermediate data structures released
10934 
10935    Level: advanced
10936 
10937    Notes:
10938 
10939 .seealso: MatPtAP(), MatMatMult()
10940 @*/
10941 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
10942 {
10943   PetscErrorCode ierr;
10944 
10945   PetscFunctionBegin;
10946   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10947   PetscValidType(mat,1);
10948   if (mat->ops->freeintermediatedatastructures) {
10949     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
10950   }
10951   PetscFunctionReturn(0);
10952 }
10953