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