xref: /petsc/src/mat/interface/matrix.c (revision 1873fc9fedfc3bd8fc2f82ccd29ab8b44a80f1db)
1 /*
2    This is where the abstract matrix operations are defined
3 */
4 
5 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
6 #include <petsc/private/isimpl.h>
7 #include <petsc/private/vecimpl.h>
8 
9 /* Logging support */
10 PetscClassId MAT_CLASSID;
11 PetscClassId MAT_COLORING_CLASSID;
12 PetscClassId MAT_FDCOLORING_CLASSID;
13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14 
15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
23 PetscLogEvent MAT_TransposeColoringCreate;
24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33 PetscLogEvent MAT_GetMultiProcBlock;
34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
35 PetscLogEvent MAT_ViennaCLCopyToGPU;
36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS;
39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
40 
41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
42 
43 /*@
44    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,
45                   for sparse matrices that already have locations it fills the locations with random numbers
46 
47    Logically Collective on Mat
48 
49    Input Parameters:
50 +  x  - the matrix
51 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52           it will create one internally.
53 
54    Output Parameter:
55 .  x  - the matrix
56 
57    Example of Usage:
58 .vb
59      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60      MatSetRandom(x,rctx);
61      PetscRandomDestroy(rctx);
62 .ve
63 
64    Level: intermediate
65 
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391   PetscFunctionReturn(0);
392 }
393 
394 /*@C
395    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
396 
397    Collective on Mat
398 
399    Input Parameter:
400 .  mat - the matrix
401 
402    Output Parameters:
403 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
404 -   ghosts - the global indices of the ghost points
405 
406    Notes:
407     the nghosts and ghosts are suitable to pass into VecCreateGhost()
408 
409    Level: advanced
410 
411 @*/
412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
413 {
414   PetscErrorCode ierr;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
418   PetscValidType(mat,1);
419   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
420   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
421   if (!mat->ops->getghosts) {
422     if (nghosts) *nghosts = 0;
423     if (ghosts) *ghosts = 0;
424   } else {
425     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
426   }
427   PetscFunctionReturn(0);
428 }
429 
430 
431 /*@
432    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
433 
434    Logically Collective on Mat
435 
436    Input Parameters:
437 .  mat - the matrix
438 
439    Level: advanced
440 
441 
442 .seealso: MatRealPart()
443 @*/
444 PetscErrorCode MatImaginaryPart(Mat mat)
445 {
446   PetscErrorCode ierr;
447 
448   PetscFunctionBegin;
449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
450   PetscValidType(mat,1);
451   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
452   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
453   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
454   MatCheckPreallocated(mat,1);
455   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
456   PetscFunctionReturn(0);
457 }
458 
459 /*@
460    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
461 
462    Not Collective
463 
464    Input Parameter:
465 .  mat - the matrix
466 
467    Output Parameters:
468 +  missing - is any diagonal missing
469 -  dd - first diagonal entry that is missing (optional) on this process
470 
471    Level: advanced
472 
473 
474 .seealso: MatRealPart()
475 @*/
476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
477 {
478   PetscErrorCode ierr;
479 
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
482   PetscValidType(mat,1);
483   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
484   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
485   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
486   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
487   PetscFunctionReturn(0);
488 }
489 
490 /*@C
491    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
492    for each row that you get to ensure that your application does
493    not bleed memory.
494 
495    Not Collective
496 
497    Input Parameters:
498 +  mat - the matrix
499 -  row - the row to get
500 
501    Output Parameters:
502 +  ncols -  if not NULL, the number of nonzeros in the row
503 .  cols - if not NULL, the column numbers
504 -  vals - if not NULL, the values
505 
506    Notes:
507    This routine is provided for people who need to have direct access
508    to the structure of a matrix.  We hope that we provide enough
509    high-level matrix routines that few users will need it.
510 
511    MatGetRow() always returns 0-based column indices, regardless of
512    whether the internal representation is 0-based (default) or 1-based.
513 
514    For better efficiency, set cols and/or vals to NULL if you do
515    not wish to extract these quantities.
516 
517    The user can only examine the values extracted with MatGetRow();
518    the values cannot be altered.  To change the matrix entries, one
519    must use MatSetValues().
520 
521    You can only have one call to MatGetRow() outstanding for a particular
522    matrix at a time, per processor. MatGetRow() can only obtain rows
523    associated with the given processor, it cannot get rows from the
524    other processors; for that we suggest using MatCreateSubMatrices(), then
525    MatGetRow() on the submatrix. The row index passed to MatGetRow()
526    is in the global number of rows.
527 
528    Fortran Notes:
529    The calling sequence from Fortran is
530 .vb
531    MatGetRow(matrix,row,ncols,cols,values,ierr)
532          Mat     matrix (input)
533          integer row    (input)
534          integer ncols  (output)
535          integer cols(maxcols) (output)
536          double precision (or double complex) values(maxcols) output
537 .ve
538    where maxcols >= maximum nonzeros in any row of the matrix.
539 
540 
541    Caution:
542    Do not try to change the contents of the output arrays (cols and vals).
543    In some cases, this may corrupt the matrix.
544 
545    Level: advanced
546 
547 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
548 @*/
549 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
550 {
551   PetscErrorCode ierr;
552   PetscInt       incols;
553 
554   PetscFunctionBegin;
555   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
556   PetscValidType(mat,1);
557   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
558   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
559   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
560   MatCheckPreallocated(mat,1);
561   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
562   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
563   if (ncols) *ncols = incols;
564   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
565   PetscFunctionReturn(0);
566 }
567 
568 /*@
569    MatConjugate - replaces the matrix values with their complex conjugates
570 
571    Logically Collective on Mat
572 
573    Input Parameters:
574 .  mat - the matrix
575 
576    Level: advanced
577 
578 .seealso:  VecConjugate()
579 @*/
580 PetscErrorCode MatConjugate(Mat mat)
581 {
582 #if defined(PETSC_USE_COMPLEX)
583   PetscErrorCode ierr;
584 
585   PetscFunctionBegin;
586   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
587   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
588   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");
589   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
590 #else
591   PetscFunctionBegin;
592 #endif
593   PetscFunctionReturn(0);
594 }
595 
596 /*@C
597    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
598 
599    Not Collective
600 
601    Input Parameters:
602 +  mat - the matrix
603 .  row - the row to get
604 .  ncols, cols - the number of nonzeros and their columns
605 -  vals - if nonzero the column values
606 
607    Notes:
608    This routine should be called after you have finished examining the entries.
609 
610    This routine zeros out ncols, cols, and vals. This is to prevent accidental
611    us of the array after it has been restored. If you pass NULL, it will
612    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
613 
614    Fortran Notes:
615    The calling sequence from Fortran is
616 .vb
617    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
618       Mat     matrix (input)
619       integer row    (input)
620       integer ncols  (output)
621       integer cols(maxcols) (output)
622       double precision (or double complex) values(maxcols) output
623 .ve
624    Where maxcols >= maximum nonzeros in any row of the matrix.
625 
626    In Fortran MatRestoreRow() MUST be called after MatGetRow()
627    before another call to MatGetRow() can be made.
628 
629    Level: advanced
630 
631 .seealso:  MatGetRow()
632 @*/
633 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
634 {
635   PetscErrorCode ierr;
636 
637   PetscFunctionBegin;
638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
639   if (ncols) PetscValidIntPointer(ncols,3);
640   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
641   if (!mat->ops->restorerow) PetscFunctionReturn(0);
642   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
643   if (ncols) *ncols = 0;
644   if (cols)  *cols = NULL;
645   if (vals)  *vals = NULL;
646   PetscFunctionReturn(0);
647 }
648 
649 /*@
650    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
651    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
652 
653    Not Collective
654 
655    Input Parameters:
656 .  mat - the matrix
657 
658    Notes:
659    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.
660 
661    Level: advanced
662 
663 .seealso: MatRestoreRowUpperTriangular()
664 @*/
665 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
666 {
667   PetscErrorCode ierr;
668 
669   PetscFunctionBegin;
670   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
671   PetscValidType(mat,1);
672   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
673   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
674   MatCheckPreallocated(mat,1);
675   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
676   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
677   PetscFunctionReturn(0);
678 }
679 
680 /*@
681    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
682 
683    Not Collective
684 
685    Input Parameters:
686 .  mat - the matrix
687 
688    Notes:
689    This routine should be called after you have finished MatGetRow/MatRestoreRow().
690 
691 
692    Level: advanced
693 
694 .seealso:  MatGetRowUpperTriangular()
695 @*/
696 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
697 {
698   PetscErrorCode ierr;
699 
700   PetscFunctionBegin;
701   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
702   PetscValidType(mat,1);
703   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
704   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
705   MatCheckPreallocated(mat,1);
706   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
707   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
708   PetscFunctionReturn(0);
709 }
710 
711 /*@C
712    MatSetOptionsPrefix - Sets the prefix used for searching for all
713    Mat options in the database.
714 
715    Logically Collective on Mat
716 
717    Input Parameter:
718 +  A - the Mat context
719 -  prefix - the prefix to prepend to all option names
720 
721    Notes:
722    A hyphen (-) must NOT be given at the beginning of the prefix name.
723    The first character of all runtime options is AUTOMATICALLY the hyphen.
724 
725    Level: advanced
726 
727 .seealso: MatSetFromOptions()
728 @*/
729 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
730 {
731   PetscErrorCode ierr;
732 
733   PetscFunctionBegin;
734   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
735   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
736   PetscFunctionReturn(0);
737 }
738 
739 /*@C
740    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
741    Mat options in the database.
742 
743    Logically Collective on Mat
744 
745    Input Parameters:
746 +  A - the Mat context
747 -  prefix - the prefix to prepend to all option names
748 
749    Notes:
750    A hyphen (-) must NOT be given at the beginning of the prefix name.
751    The first character of all runtime options is AUTOMATICALLY the hyphen.
752 
753    Level: advanced
754 
755 .seealso: MatGetOptionsPrefix()
756 @*/
757 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
758 {
759   PetscErrorCode ierr;
760 
761   PetscFunctionBegin;
762   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
763   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
764   PetscFunctionReturn(0);
765 }
766 
767 /*@C
768    MatGetOptionsPrefix - Sets the prefix used for searching for all
769    Mat options in the database.
770 
771    Not Collective
772 
773    Input Parameter:
774 .  A - the Mat context
775 
776    Output Parameter:
777 .  prefix - pointer to the prefix string used
778 
779    Notes:
780     On the fortran side, the user should pass in a string 'prefix' of
781    sufficient length to hold the prefix.
782 
783    Level: advanced
784 
785 .seealso: MatAppendOptionsPrefix()
786 @*/
787 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
788 {
789   PetscErrorCode ierr;
790 
791   PetscFunctionBegin;
792   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
793   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
794   PetscFunctionReturn(0);
795 }
796 
797 /*@
798    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
799 
800    Collective on Mat
801 
802    Input Parameters:
803 .  A - the Mat context
804 
805    Notes:
806    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
807    Currently support MPIAIJ and SEQAIJ.
808 
809    Level: beginner
810 
811 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
812 @*/
813 PetscErrorCode MatResetPreallocation(Mat A)
814 {
815   PetscErrorCode ierr;
816 
817   PetscFunctionBegin;
818   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
819   PetscValidType(A,1);
820   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
821   PetscFunctionReturn(0);
822 }
823 
824 
825 /*@
826    MatSetUp - Sets up the internal matrix data structures for the later use.
827 
828    Collective on Mat
829 
830    Input Parameters:
831 .  A - the Mat context
832 
833    Notes:
834    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
835 
836    If a suitable preallocation routine is used, this function does not need to be called.
837 
838    See the Performance chapter of the PETSc users manual for how to preallocate matrices
839 
840    Level: beginner
841 
842 .seealso: MatCreate(), MatDestroy()
843 @*/
844 PetscErrorCode MatSetUp(Mat A)
845 {
846   PetscMPIInt    size;
847   PetscErrorCode ierr;
848 
849   PetscFunctionBegin;
850   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
851   if (!((PetscObject)A)->type_name) {
852     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
853     if (size == 1) {
854       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
855     } else {
856       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
857     }
858   }
859   if (!A->preallocated && A->ops->setup) {
860     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
861     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
862   }
863   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
864   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
865   A->preallocated = PETSC_TRUE;
866   PetscFunctionReturn(0);
867 }
868 
869 #if defined(PETSC_HAVE_SAWS)
870 #include <petscviewersaws.h>
871 #endif
872 /*@C
873    MatView - Visualizes a matrix object.
874 
875    Collective on Mat
876 
877    Input Parameters:
878 +  mat - the matrix
879 -  viewer - visualization context
880 
881   Notes:
882   The available visualization contexts include
883 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
884 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
885 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
886 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
887 
888    The user can open alternative visualization contexts with
889 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
890 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
891          specified file; corresponding input uses MatLoad()
892 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
893          an X window display
894 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
895          Currently only the sequential dense and AIJ
896          matrix types support the Socket viewer.
897 
898    The user can call PetscViewerPushFormat() to specify the output
899    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
900    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
901 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
902 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
903 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
904 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
905          format common among all matrix types
906 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
907          format (which is in many cases the same as the default)
908 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
909          size and structure (not the matrix entries)
910 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
911          the matrix structure
912 
913    Options Database Keys:
914 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
915 .  -mat_view ::ascii_info_detail - Prints more detailed info
916 .  -mat_view - Prints matrix in ASCII format
917 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
918 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
919 .  -display <name> - Sets display name (default is host)
920 .  -draw_pause <sec> - Sets number of seconds to pause after display
921 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
922 .  -viewer_socket_machine <machine> -
923 .  -viewer_socket_port <port> -
924 .  -mat_view binary - save matrix to file in binary format
925 -  -viewer_binary_filename <name> -
926    Level: beginner
927 
928    Notes:
929     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
930     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
931 
932     See the manual page for MatLoad() for the exact format of the binary file when the binary
933       viewer is used.
934 
935       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
936       viewer is used.
937 
938       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
939       and then use the following mouse functions.
940 + left mouse: zoom in
941 . middle mouse: zoom out
942 - right mouse: continue with the simulation
943 
944 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
945           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
946 @*/
947 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
948 {
949   PetscErrorCode    ierr;
950   PetscInt          rows,cols,rbs,cbs;
951   PetscBool         iascii,ibinary,isstring;
952   PetscViewerFormat format;
953   PetscMPIInt       size;
954 #if defined(PETSC_HAVE_SAWS)
955   PetscBool         issaws;
956 #endif
957 
958   PetscFunctionBegin;
959   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
960   PetscValidType(mat,1);
961   if (!viewer) {
962     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
963   }
964   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
965   PetscCheckSameComm(mat,1,viewer,2);
966   MatCheckPreallocated(mat,1);
967   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
968   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
969   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
970   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
971   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
972   if (ibinary) {
973     PetscBool mpiio;
974     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
975     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
976   }
977 
978   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
979   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
980   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
981     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
982   }
983 
984 #if defined(PETSC_HAVE_SAWS)
985   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
986 #endif
987   if (iascii) {
988     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
989     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
990     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
991       MatNullSpace nullsp,transnullsp;
992 
993       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
994       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
995       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
996       if (rbs != 1 || cbs != 1) {
997         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
998         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
999       } else {
1000         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1001       }
1002       if (mat->factortype) {
1003         MatSolverType solver;
1004         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1005         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1006       }
1007       if (mat->ops->getinfo) {
1008         MatInfo info;
1009         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1010         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1011         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1012       }
1013       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1014       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1015       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1016       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1017       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1018       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1019     }
1020 #if defined(PETSC_HAVE_SAWS)
1021   } else if (issaws) {
1022     PetscMPIInt rank;
1023 
1024     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1025     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1026     if (!((PetscObject)mat)->amsmem && !rank) {
1027       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1028     }
1029 #endif
1030   } else if (isstring) {
1031     const char *type;
1032     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1033     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1034     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1035   }
1036   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1037     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1038     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1039     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1040   } else if (mat->ops->view) {
1041     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1042     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1043     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1044   }
1045   if (iascii) {
1046     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1047     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1048       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1049     }
1050   }
1051   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1052   PetscFunctionReturn(0);
1053 }
1054 
1055 #if defined(PETSC_USE_DEBUG)
1056 #include <../src/sys/totalview/tv_data_display.h>
1057 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1058 {
1059   TV_add_row("Local rows", "int", &mat->rmap->n);
1060   TV_add_row("Local columns", "int", &mat->cmap->n);
1061   TV_add_row("Global rows", "int", &mat->rmap->N);
1062   TV_add_row("Global columns", "int", &mat->cmap->N);
1063   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1064   return TV_format_OK;
1065 }
1066 #endif
1067 
1068 /*@C
1069    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1070    with MatView().  The matrix format is determined from the options database.
1071    Generates a parallel MPI matrix if the communicator has more than one
1072    processor.  The default matrix type is AIJ.
1073 
1074    Collective on PetscViewer
1075 
1076    Input Parameters:
1077 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1078             or some related function before a call to MatLoad()
1079 -  viewer - binary/HDF5 file viewer
1080 
1081    Options Database Keys:
1082    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1083    block size
1084 .    -matload_block_size <bs>
1085 
1086    Level: beginner
1087 
1088    Notes:
1089    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1090    Mat before calling this routine if you wish to set it from the options database.
1091 
1092    MatLoad() automatically loads into the options database any options
1093    given in the file filename.info where filename is the name of the file
1094    that was passed to the PetscViewerBinaryOpen(). The options in the info
1095    file will be ignored if you use the -viewer_binary_skip_info option.
1096 
1097    If the type or size of newmat is not set before a call to MatLoad, PETSc
1098    sets the default matrix type AIJ and sets the local and global sizes.
1099    If type and/or size is already set, then the same are used.
1100 
1101    In parallel, each processor can load a subset of rows (or the
1102    entire matrix).  This routine is especially useful when a large
1103    matrix is stored on disk and only part of it is desired on each
1104    processor.  For example, a parallel solver may access only some of
1105    the rows from each processor.  The algorithm used here reads
1106    relatively small blocks of data rather than reading the entire
1107    matrix and then subsetting it.
1108 
1109    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1110    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1111    or the sequence like
1112 $    PetscViewer v;
1113 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1114 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1115 $    PetscViewerSetFromOptions(v);
1116 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1117 $    PetscViewerFileSetName(v,"datafile");
1118    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1119 $ -viewer_type {binary,hdf5}
1120 
1121    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1122    and src/mat/examples/tutorials/ex10.c with the second approach.
1123 
1124    Notes about the PETSc binary format:
1125    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1126    is read onto rank 0 and then shipped to its destination rank, one after another.
1127    Multiple objects, both matrices and vectors, can be stored within the same file.
1128    Their PetscObject name is ignored; they are loaded in the order of their storage.
1129 
1130    Most users should not need to know the details of the binary storage
1131    format, since MatLoad() and MatView() completely hide these details.
1132    But for anyone who's interested, the standard binary matrix storage
1133    format is
1134 
1135 $    PetscInt    MAT_FILE_CLASSID
1136 $    PetscInt    number of rows
1137 $    PetscInt    number of columns
1138 $    PetscInt    total number of nonzeros
1139 $    PetscInt    *number nonzeros in each row
1140 $    PetscInt    *column indices of all nonzeros (starting index is zero)
1141 $    PetscScalar *values of all nonzeros
1142 
1143    PETSc automatically does the byte swapping for
1144 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1145 linux, Windows and the paragon; thus if you write your own binary
1146 read/write routines you have to swap the bytes; see PetscBinaryRead()
1147 and PetscBinaryWrite() to see how this may be done.
1148 
1149    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1150    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1151    Each processor's chunk is loaded independently by its owning rank.
1152    Multiple objects, both matrices and vectors, can be stored within the same file.
1153    They are looked up by their PetscObject name.
1154 
1155    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1156    by default the same structure and naming of the AIJ arrays and column count
1157    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1158 $    save example.mat A b -v7.3
1159    can be directly read by this routine (see Reference 1 for details).
1160    Note that depending on your MATLAB version, this format might be a default,
1161    otherwise you can set it as default in Preferences.
1162 
1163    Unless -nocompression flag is used to save the file in MATLAB,
1164    PETSc must be configured with ZLIB package.
1165 
1166    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1167 
1168    Current HDF5 (MAT-File) limitations:
1169    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1170 
1171    Corresponding MatView() is not yet implemented.
1172 
1173    The loaded matrix is actually a transpose of the original one in MATLAB,
1174    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1175    With this format, matrix is automatically transposed by PETSc,
1176    unless the matrix is marked as SPD or symmetric
1177    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1178 
1179    References:
1180 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1181 
1182 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1183 
1184  @*/
1185 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1186 {
1187   PetscErrorCode ierr;
1188   PetscBool      flg;
1189 
1190   PetscFunctionBegin;
1191   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1192   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1193 
1194   if (!((PetscObject)newmat)->type_name) {
1195     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1196   }
1197 
1198   flg  = PETSC_FALSE;
1199   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1200   if (flg) {
1201     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1202     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1203   }
1204   flg  = PETSC_FALSE;
1205   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1206   if (flg) {
1207     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1208   }
1209 
1210   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1211   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1212   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1213   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1214   PetscFunctionReturn(0);
1215 }
1216 
1217 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1218 {
1219   PetscErrorCode ierr;
1220   Mat_Redundant  *redund = *redundant;
1221   PetscInt       i;
1222 
1223   PetscFunctionBegin;
1224   if (redund){
1225     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1226       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1227       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1228       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1229     } else {
1230       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1231       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1232       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1233       for (i=0; i<redund->nrecvs; i++) {
1234         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1235         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1236       }
1237       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1238     }
1239 
1240     if (redund->subcomm) {
1241       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1242     }
1243     ierr = PetscFree(redund);CHKERRQ(ierr);
1244   }
1245   PetscFunctionReturn(0);
1246 }
1247 
1248 /*@
1249    MatDestroy - Frees space taken by a matrix.
1250 
1251    Collective on Mat
1252 
1253    Input Parameter:
1254 .  A - the matrix
1255 
1256    Level: beginner
1257 
1258 @*/
1259 PetscErrorCode MatDestroy(Mat *A)
1260 {
1261   PetscErrorCode ierr;
1262 
1263   PetscFunctionBegin;
1264   if (!*A) PetscFunctionReturn(0);
1265   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1266   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1267 
1268   /* if memory was published with SAWs then destroy it */
1269   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1270   if ((*A)->ops->destroy) {
1271     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1272   }
1273 
1274   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1275   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1276   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1277   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1278   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1279   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1280   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1281   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1282   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1283   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1284   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1285   PetscFunctionReturn(0);
1286 }
1287 
1288 /*@C
1289    MatSetValues - Inserts or adds a block of values into a matrix.
1290    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1291    MUST be called after all calls to MatSetValues() have been completed.
1292 
1293    Not Collective
1294 
1295    Input Parameters:
1296 +  mat - the matrix
1297 .  v - a logically two-dimensional array of values
1298 .  m, idxm - the number of rows and their global indices
1299 .  n, idxn - the number of columns and their global indices
1300 -  addv - either ADD_VALUES or INSERT_VALUES, where
1301    ADD_VALUES adds values to any existing entries, and
1302    INSERT_VALUES replaces existing entries with new values
1303 
1304    Notes:
1305    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1306       MatSetUp() before using this routine
1307 
1308    By default the values, v, are row-oriented. See MatSetOption() for other options.
1309 
1310    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1311    options cannot be mixed without intervening calls to the assembly
1312    routines.
1313 
1314    MatSetValues() uses 0-based row and column numbers in Fortran
1315    as well as in C.
1316 
1317    Negative indices may be passed in idxm and idxn, these rows and columns are
1318    simply ignored. This allows easily inserting element stiffness matrices
1319    with homogeneous Dirchlet boundary conditions that you don't want represented
1320    in the matrix.
1321 
1322    Efficiency Alert:
1323    The routine MatSetValuesBlocked() may offer much better efficiency
1324    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1325 
1326    Level: beginner
1327 
1328    Developer Notes:
1329     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1330                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1331 
1332 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1333           InsertMode, INSERT_VALUES, ADD_VALUES
1334 @*/
1335 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1336 {
1337   PetscErrorCode ierr;
1338 #if defined(PETSC_USE_DEBUG)
1339   PetscInt       i,j;
1340 #endif
1341 
1342   PetscFunctionBeginHot;
1343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1344   PetscValidType(mat,1);
1345   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1346   PetscValidIntPointer(idxm,3);
1347   PetscValidIntPointer(idxn,5);
1348   MatCheckPreallocated(mat,1);
1349 
1350   if (mat->insertmode == NOT_SET_VALUES) {
1351     mat->insertmode = addv;
1352   }
1353 #if defined(PETSC_USE_DEBUG)
1354   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1355   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1356   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1357 
1358   for (i=0; i<m; i++) {
1359     for (j=0; j<n; j++) {
1360       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1361 #if defined(PETSC_USE_COMPLEX)
1362         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]);
1363 #else
1364         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1365 #endif
1366     }
1367   }
1368 #endif
1369 
1370   if (mat->assembled) {
1371     mat->was_assembled = PETSC_TRUE;
1372     mat->assembled     = PETSC_FALSE;
1373   }
1374   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1375   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1376   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1377   PetscFunctionReturn(0);
1378 }
1379 
1380 
1381 /*@
1382    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1383         values into a matrix
1384 
1385    Not Collective
1386 
1387    Input Parameters:
1388 +  mat - the matrix
1389 .  row - the (block) row to set
1390 -  v - a logically two-dimensional array of values
1391 
1392    Notes:
1393    By the values, v, are column-oriented (for the block version) and sorted
1394 
1395    All the nonzeros in the row must be provided
1396 
1397    The matrix must have previously had its column indices set
1398 
1399    The row must belong to this process
1400 
1401    Level: intermediate
1402 
1403 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1404           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1405 @*/
1406 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1407 {
1408   PetscErrorCode ierr;
1409   PetscInt       globalrow;
1410 
1411   PetscFunctionBegin;
1412   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1413   PetscValidType(mat,1);
1414   PetscValidScalarPointer(v,2);
1415   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1416   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1417   PetscFunctionReturn(0);
1418 }
1419 
1420 /*@
1421    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1422         values into a matrix
1423 
1424    Not Collective
1425 
1426    Input Parameters:
1427 +  mat - the matrix
1428 .  row - the (block) row to set
1429 -  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
1430 
1431    Notes:
1432    The values, v, are column-oriented for the block version.
1433 
1434    All the nonzeros in the row must be provided
1435 
1436    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1437 
1438    The row must belong to this process
1439 
1440    Level: advanced
1441 
1442 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1443           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1444 @*/
1445 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1446 {
1447   PetscErrorCode ierr;
1448 
1449   PetscFunctionBeginHot;
1450   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1451   PetscValidType(mat,1);
1452   MatCheckPreallocated(mat,1);
1453   PetscValidScalarPointer(v,2);
1454 #if defined(PETSC_USE_DEBUG)
1455   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1456   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1457 #endif
1458   mat->insertmode = INSERT_VALUES;
1459 
1460   if (mat->assembled) {
1461     mat->was_assembled = PETSC_TRUE;
1462     mat->assembled     = PETSC_FALSE;
1463   }
1464   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1465   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1466   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1467   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1468   PetscFunctionReturn(0);
1469 }
1470 
1471 /*@
1472    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1473      Using structured grid indexing
1474 
1475    Not Collective
1476 
1477    Input Parameters:
1478 +  mat - the matrix
1479 .  m - number of rows being entered
1480 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1481 .  n - number of columns being entered
1482 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1483 .  v - a logically two-dimensional array of values
1484 -  addv - either ADD_VALUES or INSERT_VALUES, where
1485    ADD_VALUES adds values to any existing entries, and
1486    INSERT_VALUES replaces existing entries with new values
1487 
1488    Notes:
1489    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1490 
1491    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1492    options cannot be mixed without intervening calls to the assembly
1493    routines.
1494 
1495    The grid coordinates are across the entire grid, not just the local portion
1496 
1497    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1498    as well as in C.
1499 
1500    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1501 
1502    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1503    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1504 
1505    The columns and rows in the stencil passed in MUST be contained within the
1506    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1507    if you create a DMDA with an overlap of one grid level and on a particular process its first
1508    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1509    first i index you can use in your column and row indices in MatSetStencil() is 5.
1510 
1511    In Fortran idxm and idxn should be declared as
1512 $     MatStencil idxm(4,m),idxn(4,n)
1513    and the values inserted using
1514 $    idxm(MatStencil_i,1) = i
1515 $    idxm(MatStencil_j,1) = j
1516 $    idxm(MatStencil_k,1) = k
1517 $    idxm(MatStencil_c,1) = c
1518    etc
1519 
1520    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1521    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1522    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1523    DM_BOUNDARY_PERIODIC boundary type.
1524 
1525    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
1526    a single value per point) you can skip filling those indices.
1527 
1528    Inspired by the structured grid interface to the HYPRE package
1529    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1530 
1531    Efficiency Alert:
1532    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1533    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1534 
1535    Level: beginner
1536 
1537 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1538           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1539 @*/
1540 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1541 {
1542   PetscErrorCode ierr;
1543   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1544   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1545   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1546 
1547   PetscFunctionBegin;
1548   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1549   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1550   PetscValidType(mat,1);
1551   PetscValidIntPointer(idxm,3);
1552   PetscValidIntPointer(idxn,5);
1553 
1554   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1555     jdxm = buf; jdxn = buf+m;
1556   } else {
1557     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1558     jdxm = bufm; jdxn = bufn;
1559   }
1560   for (i=0; i<m; i++) {
1561     for (j=0; j<3-sdim; j++) dxm++;
1562     tmp = *dxm++ - starts[0];
1563     for (j=0; j<dim-1; j++) {
1564       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1565       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1566     }
1567     if (mat->stencil.noc) dxm++;
1568     jdxm[i] = tmp;
1569   }
1570   for (i=0; i<n; i++) {
1571     for (j=0; j<3-sdim; j++) dxn++;
1572     tmp = *dxn++ - starts[0];
1573     for (j=0; j<dim-1; j++) {
1574       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1575       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1576     }
1577     if (mat->stencil.noc) dxn++;
1578     jdxn[i] = tmp;
1579   }
1580   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1581   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1582   PetscFunctionReturn(0);
1583 }
1584 
1585 /*@
1586    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1587      Using structured grid indexing
1588 
1589    Not Collective
1590 
1591    Input Parameters:
1592 +  mat - the matrix
1593 .  m - number of rows being entered
1594 .  idxm - grid coordinates for matrix rows being entered
1595 .  n - number of columns being entered
1596 .  idxn - grid coordinates for matrix columns being entered
1597 .  v - a logically two-dimensional array of values
1598 -  addv - either ADD_VALUES or INSERT_VALUES, where
1599    ADD_VALUES adds values to any existing entries, and
1600    INSERT_VALUES replaces existing entries with new values
1601 
1602    Notes:
1603    By default the values, v, are row-oriented and unsorted.
1604    See MatSetOption() for other options.
1605 
1606    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1607    options cannot be mixed without intervening calls to the assembly
1608    routines.
1609 
1610    The grid coordinates are across the entire grid, not just the local portion
1611 
1612    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1613    as well as in C.
1614 
1615    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1616 
1617    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1618    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1619 
1620    The columns and rows in the stencil passed in MUST be contained within the
1621    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1622    if you create a DMDA with an overlap of one grid level and on a particular process its first
1623    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1624    first i index you can use in your column and row indices in MatSetStencil() is 5.
1625 
1626    In Fortran idxm and idxn should be declared as
1627 $     MatStencil idxm(4,m),idxn(4,n)
1628    and the values inserted using
1629 $    idxm(MatStencil_i,1) = i
1630 $    idxm(MatStencil_j,1) = j
1631 $    idxm(MatStencil_k,1) = k
1632    etc
1633 
1634    Negative indices may be passed in idxm and idxn, these rows and columns are
1635    simply ignored. This allows easily inserting element stiffness matrices
1636    with homogeneous Dirchlet boundary conditions that you don't want represented
1637    in the matrix.
1638 
1639    Inspired by the structured grid interface to the HYPRE package
1640    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1641 
1642    Level: beginner
1643 
1644 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1645           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1646           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1647 @*/
1648 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1649 {
1650   PetscErrorCode ierr;
1651   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1652   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1653   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1654 
1655   PetscFunctionBegin;
1656   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1657   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1658   PetscValidType(mat,1);
1659   PetscValidIntPointer(idxm,3);
1660   PetscValidIntPointer(idxn,5);
1661   PetscValidScalarPointer(v,6);
1662 
1663   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1664     jdxm = buf; jdxn = buf+m;
1665   } else {
1666     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1667     jdxm = bufm; jdxn = bufn;
1668   }
1669   for (i=0; i<m; i++) {
1670     for (j=0; j<3-sdim; j++) dxm++;
1671     tmp = *dxm++ - starts[0];
1672     for (j=0; j<sdim-1; j++) {
1673       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1674       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1675     }
1676     dxm++;
1677     jdxm[i] = tmp;
1678   }
1679   for (i=0; i<n; i++) {
1680     for (j=0; j<3-sdim; j++) dxn++;
1681     tmp = *dxn++ - starts[0];
1682     for (j=0; j<sdim-1; j++) {
1683       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1684       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1685     }
1686     dxn++;
1687     jdxn[i] = tmp;
1688   }
1689   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1690   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1691   PetscFunctionReturn(0);
1692 }
1693 
1694 /*@
1695    MatSetStencil - Sets the grid information for setting values into a matrix via
1696         MatSetValuesStencil()
1697 
1698    Not Collective
1699 
1700    Input Parameters:
1701 +  mat - the matrix
1702 .  dim - dimension of the grid 1, 2, or 3
1703 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1704 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1705 -  dof - number of degrees of freedom per node
1706 
1707 
1708    Inspired by the structured grid interface to the HYPRE package
1709    (www.llnl.gov/CASC/hyper)
1710 
1711    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1712    user.
1713 
1714    Level: beginner
1715 
1716 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1717           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1718 @*/
1719 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1720 {
1721   PetscInt i;
1722 
1723   PetscFunctionBegin;
1724   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1725   PetscValidIntPointer(dims,3);
1726   PetscValidIntPointer(starts,4);
1727 
1728   mat->stencil.dim = dim + (dof > 1);
1729   for (i=0; i<dim; i++) {
1730     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1731     mat->stencil.starts[i] = starts[dim-i-1];
1732   }
1733   mat->stencil.dims[dim]   = dof;
1734   mat->stencil.starts[dim] = 0;
1735   mat->stencil.noc         = (PetscBool)(dof == 1);
1736   PetscFunctionReturn(0);
1737 }
1738 
1739 /*@C
1740    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1741 
1742    Not Collective
1743 
1744    Input Parameters:
1745 +  mat - the matrix
1746 .  v - a logically two-dimensional array of values
1747 .  m, idxm - the number of block rows and their global block indices
1748 .  n, idxn - the number of block columns and their global block indices
1749 -  addv - either ADD_VALUES or INSERT_VALUES, where
1750    ADD_VALUES adds values to any existing entries, and
1751    INSERT_VALUES replaces existing entries with new values
1752 
1753    Notes:
1754    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1755    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1756 
1757    The m and n count the NUMBER of blocks in the row direction and column direction,
1758    NOT the total number of rows/columns; for example, if the block size is 2 and
1759    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1760    The values in idxm would be 1 2; that is the first index for each block divided by
1761    the block size.
1762 
1763    Note that you must call MatSetBlockSize() when constructing this matrix (before
1764    preallocating it).
1765 
1766    By default the values, v, are row-oriented, so the layout of
1767    v is the same as for MatSetValues(). See MatSetOption() for other options.
1768 
1769    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1770    options cannot be mixed without intervening calls to the assembly
1771    routines.
1772 
1773    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1774    as well as in C.
1775 
1776    Negative indices may be passed in idxm and idxn, these rows and columns are
1777    simply ignored. This allows easily inserting element stiffness matrices
1778    with homogeneous Dirchlet boundary conditions that you don't want represented
1779    in the matrix.
1780 
1781    Each time an entry is set within a sparse matrix via MatSetValues(),
1782    internal searching must be done to determine where to place the
1783    data in the matrix storage space.  By instead inserting blocks of
1784    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1785    reduced.
1786 
1787    Example:
1788 $   Suppose m=n=2 and block size(bs) = 2 The array is
1789 $
1790 $   1  2  | 3  4
1791 $   5  6  | 7  8
1792 $   - - - | - - -
1793 $   9  10 | 11 12
1794 $   13 14 | 15 16
1795 $
1796 $   v[] should be passed in like
1797 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1798 $
1799 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1800 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1801 
1802    Level: intermediate
1803 
1804 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1805 @*/
1806 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1807 {
1808   PetscErrorCode ierr;
1809 
1810   PetscFunctionBeginHot;
1811   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1812   PetscValidType(mat,1);
1813   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1814   PetscValidIntPointer(idxm,3);
1815   PetscValidIntPointer(idxn,5);
1816   PetscValidScalarPointer(v,6);
1817   MatCheckPreallocated(mat,1);
1818   if (mat->insertmode == NOT_SET_VALUES) {
1819     mat->insertmode = addv;
1820   }
1821 #if defined(PETSC_USE_DEBUG)
1822   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1823   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1824   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1825 #endif
1826 
1827   if (mat->assembled) {
1828     mat->was_assembled = PETSC_TRUE;
1829     mat->assembled     = PETSC_FALSE;
1830   }
1831   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1832   if (mat->ops->setvaluesblocked) {
1833     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1834   } else {
1835     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1836     PetscInt i,j,bs,cbs;
1837     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1838     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1839       iidxm = buf; iidxn = buf + m*bs;
1840     } else {
1841       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1842       iidxm = bufr; iidxn = bufc;
1843     }
1844     for (i=0; i<m; i++) {
1845       for (j=0; j<bs; j++) {
1846         iidxm[i*bs+j] = bs*idxm[i] + j;
1847       }
1848     }
1849     for (i=0; i<n; i++) {
1850       for (j=0; j<cbs; j++) {
1851         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1852       }
1853     }
1854     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1855     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1856   }
1857   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1858   PetscFunctionReturn(0);
1859 }
1860 
1861 /*@
1862    MatGetValues - Gets a block of values from a matrix.
1863 
1864    Not Collective; currently only returns a local block
1865 
1866    Input Parameters:
1867 +  mat - the matrix
1868 .  v - a logically two-dimensional array for storing the values
1869 .  m, idxm - the number of rows and their global indices
1870 -  n, idxn - the number of columns and their global indices
1871 
1872    Notes:
1873    The user must allocate space (m*n PetscScalars) for the values, v.
1874    The values, v, are then returned in a row-oriented format,
1875    analogous to that used by default in MatSetValues().
1876 
1877    MatGetValues() uses 0-based row and column numbers in
1878    Fortran as well as in C.
1879 
1880    MatGetValues() requires that the matrix has been assembled
1881    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1882    MatSetValues() and MatGetValues() CANNOT be made in succession
1883    without intermediate matrix assembly.
1884 
1885    Negative row or column indices will be ignored and those locations in v[] will be
1886    left unchanged.
1887 
1888    Level: advanced
1889 
1890 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1891 @*/
1892 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1893 {
1894   PetscErrorCode ierr;
1895 
1896   PetscFunctionBegin;
1897   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1898   PetscValidType(mat,1);
1899   if (!m || !n) PetscFunctionReturn(0);
1900   PetscValidIntPointer(idxm,3);
1901   PetscValidIntPointer(idxn,5);
1902   PetscValidScalarPointer(v,6);
1903   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1904   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1905   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1906   MatCheckPreallocated(mat,1);
1907 
1908   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1909   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1910   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1911   PetscFunctionReturn(0);
1912 }
1913 
1914 /*@
1915   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1916   the same size. Currently, this can only be called once and creates the given matrix.
1917 
1918   Not Collective
1919 
1920   Input Parameters:
1921 + mat - the matrix
1922 . nb - the number of blocks
1923 . bs - the number of rows (and columns) in each block
1924 . rows - a concatenation of the rows for each block
1925 - v - a concatenation of logically two-dimensional arrays of values
1926 
1927   Notes:
1928   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1929 
1930   Level: advanced
1931 
1932 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1933           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1934 @*/
1935 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1936 {
1937   PetscErrorCode ierr;
1938 
1939   PetscFunctionBegin;
1940   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1941   PetscValidType(mat,1);
1942   PetscValidScalarPointer(rows,4);
1943   PetscValidScalarPointer(v,5);
1944 #if defined(PETSC_USE_DEBUG)
1945   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1946 #endif
1947 
1948   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1949   if (mat->ops->setvaluesbatch) {
1950     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1951   } else {
1952     PetscInt b;
1953     for (b = 0; b < nb; ++b) {
1954       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1955     }
1956   }
1957   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 /*@
1962    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1963    the routine MatSetValuesLocal() to allow users to insert matrix entries
1964    using a local (per-processor) numbering.
1965 
1966    Not Collective
1967 
1968    Input Parameters:
1969 +  x - the matrix
1970 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1971 - cmapping - column mapping
1972 
1973    Level: intermediate
1974 
1975 
1976 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1977 @*/
1978 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1979 {
1980   PetscErrorCode ierr;
1981 
1982   PetscFunctionBegin;
1983   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
1984   PetscValidType(x,1);
1985   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
1986   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
1987 
1988   if (x->ops->setlocaltoglobalmapping) {
1989     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
1990   } else {
1991     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
1992     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
1993   }
1994   PetscFunctionReturn(0);
1995 }
1996 
1997 
1998 /*@
1999    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2000 
2001    Not Collective
2002 
2003    Input Parameters:
2004 .  A - the matrix
2005 
2006    Output Parameters:
2007 + rmapping - row mapping
2008 - cmapping - column mapping
2009 
2010    Level: advanced
2011 
2012 
2013 .seealso:  MatSetValuesLocal()
2014 @*/
2015 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2016 {
2017   PetscFunctionBegin;
2018   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2019   PetscValidType(A,1);
2020   if (rmapping) PetscValidPointer(rmapping,2);
2021   if (cmapping) PetscValidPointer(cmapping,3);
2022   if (rmapping) *rmapping = A->rmap->mapping;
2023   if (cmapping) *cmapping = A->cmap->mapping;
2024   PetscFunctionReturn(0);
2025 }
2026 
2027 /*@
2028    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2029 
2030    Not Collective
2031 
2032    Input Parameters:
2033 .  A - the matrix
2034 
2035    Output Parameters:
2036 + rmap - row layout
2037 - cmap - column layout
2038 
2039    Level: advanced
2040 
2041 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2042 @*/
2043 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2044 {
2045   PetscFunctionBegin;
2046   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2047   PetscValidType(A,1);
2048   if (rmap) PetscValidPointer(rmap,2);
2049   if (cmap) PetscValidPointer(cmap,3);
2050   if (rmap) *rmap = A->rmap;
2051   if (cmap) *cmap = A->cmap;
2052   PetscFunctionReturn(0);
2053 }
2054 
2055 /*@C
2056    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2057    using a local ordering of the nodes.
2058 
2059    Not Collective
2060 
2061    Input Parameters:
2062 +  mat - the matrix
2063 .  nrow, irow - number of rows and their local indices
2064 .  ncol, icol - number of columns and their local indices
2065 .  y -  a logically two-dimensional array of values
2066 -  addv - either INSERT_VALUES or ADD_VALUES, where
2067    ADD_VALUES adds values to any existing entries, and
2068    INSERT_VALUES replaces existing entries with new values
2069 
2070    Notes:
2071    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2072       MatSetUp() before using this routine
2073 
2074    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2075 
2076    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2077    options cannot be mixed without intervening calls to the assembly
2078    routines.
2079 
2080    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2081    MUST be called after all calls to MatSetValuesLocal() have been completed.
2082 
2083    Level: intermediate
2084 
2085    Developer Notes:
2086     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2087                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2088 
2089 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2090            MatSetValueLocal()
2091 @*/
2092 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2093 {
2094   PetscErrorCode ierr;
2095 
2096   PetscFunctionBeginHot;
2097   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2098   PetscValidType(mat,1);
2099   MatCheckPreallocated(mat,1);
2100   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2101   PetscValidIntPointer(irow,3);
2102   PetscValidIntPointer(icol,5);
2103   if (mat->insertmode == NOT_SET_VALUES) {
2104     mat->insertmode = addv;
2105   }
2106 #if defined(PETSC_USE_DEBUG)
2107   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2108   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2109   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2110 #endif
2111 
2112   if (mat->assembled) {
2113     mat->was_assembled = PETSC_TRUE;
2114     mat->assembled     = PETSC_FALSE;
2115   }
2116   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2117   if (mat->ops->setvalueslocal) {
2118     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2119   } else {
2120     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2121     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2122       irowm = buf; icolm = buf+nrow;
2123     } else {
2124       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2125       irowm = bufr; icolm = bufc;
2126     }
2127     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2128     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2129     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2130     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2131   }
2132   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2133   PetscFunctionReturn(0);
2134 }
2135 
2136 /*@C
2137    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2138    using a local ordering of the nodes a block at a time.
2139 
2140    Not Collective
2141 
2142    Input Parameters:
2143 +  x - the matrix
2144 .  nrow, irow - number of rows and their local indices
2145 .  ncol, icol - number of columns and their local indices
2146 .  y -  a logically two-dimensional array of values
2147 -  addv - either INSERT_VALUES or ADD_VALUES, where
2148    ADD_VALUES adds values to any existing entries, and
2149    INSERT_VALUES replaces existing entries with new values
2150 
2151    Notes:
2152    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2153       MatSetUp() before using this routine
2154 
2155    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2156       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2157 
2158    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2159    options cannot be mixed without intervening calls to the assembly
2160    routines.
2161 
2162    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2163    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2164 
2165    Level: intermediate
2166 
2167    Developer Notes:
2168     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2169                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2170 
2171 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2172            MatSetValuesLocal(),  MatSetValuesBlocked()
2173 @*/
2174 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2175 {
2176   PetscErrorCode ierr;
2177 
2178   PetscFunctionBeginHot;
2179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2180   PetscValidType(mat,1);
2181   MatCheckPreallocated(mat,1);
2182   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2183   PetscValidIntPointer(irow,3);
2184   PetscValidIntPointer(icol,5);
2185   PetscValidScalarPointer(y,6);
2186   if (mat->insertmode == NOT_SET_VALUES) {
2187     mat->insertmode = addv;
2188   }
2189 #if defined(PETSC_USE_DEBUG)
2190   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2191   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2192   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);
2193 #endif
2194 
2195   if (mat->assembled) {
2196     mat->was_assembled = PETSC_TRUE;
2197     mat->assembled     = PETSC_FALSE;
2198   }
2199 #if defined(PETSC_USE_DEBUG)
2200   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2201   if (mat->rmap->mapping) {
2202     PetscInt irbs, rbs;
2203     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2204     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2205     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2206   }
2207   if (mat->cmap->mapping) {
2208     PetscInt icbs, cbs;
2209     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2210     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2211     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2212   }
2213 #endif
2214   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2215   if (mat->ops->setvaluesblockedlocal) {
2216     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2217   } else {
2218     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2219     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2220       irowm = buf; icolm = buf + nrow;
2221     } else {
2222       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2223       irowm = bufr; icolm = bufc;
2224     }
2225     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2226     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2227     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2228     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2229   }
2230   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2231   PetscFunctionReturn(0);
2232 }
2233 
2234 /*@
2235    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2236 
2237    Collective on Mat
2238 
2239    Input Parameters:
2240 +  mat - the matrix
2241 -  x   - the vector to be multiplied
2242 
2243    Output Parameters:
2244 .  y - the result
2245 
2246    Notes:
2247    The vectors x and y cannot be the same.  I.e., one cannot
2248    call MatMult(A,y,y).
2249 
2250    Level: developer
2251 
2252 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2253 @*/
2254 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2255 {
2256   PetscErrorCode ierr;
2257 
2258   PetscFunctionBegin;
2259   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2260   PetscValidType(mat,1);
2261   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2262   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2263 
2264   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2265   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2266   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2267   MatCheckPreallocated(mat,1);
2268 
2269   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2270   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2271   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2272   PetscFunctionReturn(0);
2273 }
2274 
2275 /* --------------------------------------------------------*/
2276 /*@
2277    MatMult - Computes the matrix-vector product, y = Ax.
2278 
2279    Neighbor-wise Collective on Mat
2280 
2281    Input Parameters:
2282 +  mat - the matrix
2283 -  x   - the vector to be multiplied
2284 
2285    Output Parameters:
2286 .  y - the result
2287 
2288    Notes:
2289    The vectors x and y cannot be the same.  I.e., one cannot
2290    call MatMult(A,y,y).
2291 
2292    Level: beginner
2293 
2294 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2295 @*/
2296 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2297 {
2298   PetscErrorCode ierr;
2299 
2300   PetscFunctionBegin;
2301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2302   PetscValidType(mat,1);
2303   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2304   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2305   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2306   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2307   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2308 #if !defined(PETSC_HAVE_CONSTRAINTS)
2309   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);
2310   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);
2311   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);
2312 #endif
2313   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2314   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2315   MatCheckPreallocated(mat,1);
2316 
2317   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2318   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2319   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2320   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2321   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2322   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2323   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2324   PetscFunctionReturn(0);
2325 }
2326 
2327 /*@
2328    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2329 
2330    Neighbor-wise Collective on Mat
2331 
2332    Input Parameters:
2333 +  mat - the matrix
2334 -  x   - the vector to be multiplied
2335 
2336    Output Parameters:
2337 .  y - the result
2338 
2339    Notes:
2340    The vectors x and y cannot be the same.  I.e., one cannot
2341    call MatMultTranspose(A,y,y).
2342 
2343    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2344    use MatMultHermitianTranspose()
2345 
2346    Level: beginner
2347 
2348 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2349 @*/
2350 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2351 {
2352   PetscErrorCode ierr;
2353 
2354   PetscFunctionBegin;
2355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2356   PetscValidType(mat,1);
2357   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2358   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2359 
2360   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2361   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2362   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2363 #if !defined(PETSC_HAVE_CONSTRAINTS)
2364   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);
2365   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);
2366 #endif
2367   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2368   MatCheckPreallocated(mat,1);
2369 
2370   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2371   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2372   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2373   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2374   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2375   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2376   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2377   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2378   PetscFunctionReturn(0);
2379 }
2380 
2381 /*@
2382    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2383 
2384    Neighbor-wise Collective on Mat
2385 
2386    Input Parameters:
2387 +  mat - the matrix
2388 -  x   - the vector to be multilplied
2389 
2390    Output Parameters:
2391 .  y - the result
2392 
2393    Notes:
2394    The vectors x and y cannot be the same.  I.e., one cannot
2395    call MatMultHermitianTranspose(A,y,y).
2396 
2397    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2398 
2399    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2400 
2401    Level: beginner
2402 
2403 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2404 @*/
2405 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2406 {
2407   PetscErrorCode ierr;
2408   Vec            w;
2409 
2410   PetscFunctionBegin;
2411   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2412   PetscValidType(mat,1);
2413   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2414   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2415 
2416   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2417   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2418   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2419 #if !defined(PETSC_HAVE_CONSTRAINTS)
2420   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);
2421   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);
2422 #endif
2423   MatCheckPreallocated(mat,1);
2424 
2425   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2426   if (mat->ops->multhermitiantranspose) {
2427     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2428     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2429     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2430   } else {
2431     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2432     ierr = VecCopy(x,w);CHKERRQ(ierr);
2433     ierr = VecConjugate(w);CHKERRQ(ierr);
2434     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2435     ierr = VecDestroy(&w);CHKERRQ(ierr);
2436     ierr = VecConjugate(y);CHKERRQ(ierr);
2437   }
2438   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2439   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2440   PetscFunctionReturn(0);
2441 }
2442 
2443 /*@
2444     MatMultAdd -  Computes v3 = v2 + A * v1.
2445 
2446     Neighbor-wise Collective on Mat
2447 
2448     Input Parameters:
2449 +   mat - the matrix
2450 -   v1, v2 - the vectors
2451 
2452     Output Parameters:
2453 .   v3 - the result
2454 
2455     Notes:
2456     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2457     call MatMultAdd(A,v1,v2,v1).
2458 
2459     Level: beginner
2460 
2461 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2462 @*/
2463 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2464 {
2465   PetscErrorCode ierr;
2466 
2467   PetscFunctionBegin;
2468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2469   PetscValidType(mat,1);
2470   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2471   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2472   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2473 
2474   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2475   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2476   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);
2477   /* 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);
2478      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); */
2479   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);
2480   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);
2481   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2482   MatCheckPreallocated(mat,1);
2483 
2484   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2485   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2486   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2487   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2488   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2489   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2490   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2491   PetscFunctionReturn(0);
2492 }
2493 
2494 /*@
2495    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2496 
2497    Neighbor-wise Collective on Mat
2498 
2499    Input Parameters:
2500 +  mat - the matrix
2501 -  v1, v2 - the vectors
2502 
2503    Output Parameters:
2504 .  v3 - the result
2505 
2506    Notes:
2507    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2508    call MatMultTransposeAdd(A,v1,v2,v1).
2509 
2510    Level: beginner
2511 
2512 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2513 @*/
2514 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2515 {
2516   PetscErrorCode ierr;
2517 
2518   PetscFunctionBegin;
2519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2520   PetscValidType(mat,1);
2521   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2522   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2523   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2524 
2525   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2526   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2527   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2528   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2529   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);
2530   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);
2531   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);
2532   MatCheckPreallocated(mat,1);
2533 
2534   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2535   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2536   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2537   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2538   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2539   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2540   PetscFunctionReturn(0);
2541 }
2542 
2543 /*@
2544    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2545 
2546    Neighbor-wise Collective on Mat
2547 
2548    Input Parameters:
2549 +  mat - the matrix
2550 -  v1, v2 - the vectors
2551 
2552    Output Parameters:
2553 .  v3 - the result
2554 
2555    Notes:
2556    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2557    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2558 
2559    Level: beginner
2560 
2561 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2562 @*/
2563 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2564 {
2565   PetscErrorCode ierr;
2566 
2567   PetscFunctionBegin;
2568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2569   PetscValidType(mat,1);
2570   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2571   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2572   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2573 
2574   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2575   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2576   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2577   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2578   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2579   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2580   MatCheckPreallocated(mat,1);
2581 
2582   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2583   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2584   if (mat->ops->multhermitiantransposeadd) {
2585     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2586   } else {
2587     Vec w,z;
2588     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2589     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2590     ierr = VecConjugate(w);CHKERRQ(ierr);
2591     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2592     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2593     ierr = VecDestroy(&w);CHKERRQ(ierr);
2594     ierr = VecConjugate(z);CHKERRQ(ierr);
2595     if (v2 != v3) {
2596       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2597     } else {
2598       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2599     }
2600     ierr = VecDestroy(&z);CHKERRQ(ierr);
2601   }
2602   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2603   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2604   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2605   PetscFunctionReturn(0);
2606 }
2607 
2608 /*@
2609    MatMultConstrained - The inner multiplication routine for a
2610    constrained matrix P^T A P.
2611 
2612    Neighbor-wise Collective on Mat
2613 
2614    Input Parameters:
2615 +  mat - the matrix
2616 -  x   - the vector to be multilplied
2617 
2618    Output Parameters:
2619 .  y - the result
2620 
2621    Notes:
2622    The vectors x and y cannot be the same.  I.e., one cannot
2623    call MatMult(A,y,y).
2624 
2625    Level: beginner
2626 
2627 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2628 @*/
2629 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2630 {
2631   PetscErrorCode ierr;
2632 
2633   PetscFunctionBegin;
2634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2635   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2636   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2637   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2638   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2639   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2640   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);
2641   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);
2642   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);
2643 
2644   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2645   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2646   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2647   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2648   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2649   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2650   PetscFunctionReturn(0);
2651 }
2652 
2653 /*@
2654    MatMultTransposeConstrained - The inner multiplication routine for a
2655    constrained matrix P^T A^T P.
2656 
2657    Neighbor-wise Collective on Mat
2658 
2659    Input Parameters:
2660 +  mat - the matrix
2661 -  x   - the vector to be multilplied
2662 
2663    Output Parameters:
2664 .  y - the result
2665 
2666    Notes:
2667    The vectors x and y cannot be the same.  I.e., one cannot
2668    call MatMult(A,y,y).
2669 
2670    Level: beginner
2671 
2672 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2673 @*/
2674 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2675 {
2676   PetscErrorCode ierr;
2677 
2678   PetscFunctionBegin;
2679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2680   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2681   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2682   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2683   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2684   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2685   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);
2686   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);
2687 
2688   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2689   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2690   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2691   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2692   PetscFunctionReturn(0);
2693 }
2694 
2695 /*@C
2696    MatGetFactorType - gets the type of factorization it is
2697 
2698    Not Collective
2699 
2700    Input Parameters:
2701 .  mat - the matrix
2702 
2703    Output Parameters:
2704 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2705 
2706    Level: intermediate
2707 
2708 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2709 @*/
2710 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2711 {
2712   PetscFunctionBegin;
2713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2714   PetscValidType(mat,1);
2715   PetscValidPointer(t,2);
2716   *t = mat->factortype;
2717   PetscFunctionReturn(0);
2718 }
2719 
2720 /*@C
2721    MatSetFactorType - sets the type of factorization it is
2722 
2723    Logically Collective on Mat
2724 
2725    Input Parameters:
2726 +  mat - the matrix
2727 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2728 
2729    Level: intermediate
2730 
2731 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2732 @*/
2733 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2734 {
2735   PetscFunctionBegin;
2736   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2737   PetscValidType(mat,1);
2738   mat->factortype = t;
2739   PetscFunctionReturn(0);
2740 }
2741 
2742 /* ------------------------------------------------------------*/
2743 /*@C
2744    MatGetInfo - Returns information about matrix storage (number of
2745    nonzeros, memory, etc.).
2746 
2747    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2748 
2749    Input Parameters:
2750 .  mat - the matrix
2751 
2752    Output Parameters:
2753 +  flag - flag indicating the type of parameters to be returned
2754    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2755    MAT_GLOBAL_SUM - sum over all processors)
2756 -  info - matrix information context
2757 
2758    Notes:
2759    The MatInfo context contains a variety of matrix data, including
2760    number of nonzeros allocated and used, number of mallocs during
2761    matrix assembly, etc.  Additional information for factored matrices
2762    is provided (such as the fill ratio, number of mallocs during
2763    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2764    when using the runtime options
2765 $       -info -mat_view ::ascii_info
2766 
2767    Example for C/C++ Users:
2768    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2769    data within the MatInfo context.  For example,
2770 .vb
2771       MatInfo info;
2772       Mat     A;
2773       double  mal, nz_a, nz_u;
2774 
2775       MatGetInfo(A,MAT_LOCAL,&info);
2776       mal  = info.mallocs;
2777       nz_a = info.nz_allocated;
2778 .ve
2779 
2780    Example for Fortran Users:
2781    Fortran users should declare info as a double precision
2782    array of dimension MAT_INFO_SIZE, and then extract the parameters
2783    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2784    a complete list of parameter names.
2785 .vb
2786       double  precision info(MAT_INFO_SIZE)
2787       double  precision mal, nz_a
2788       Mat     A
2789       integer ierr
2790 
2791       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2792       mal = info(MAT_INFO_MALLOCS)
2793       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2794 .ve
2795 
2796     Level: intermediate
2797 
2798     Developer Note: fortran interface is not autogenerated as the f90
2799     interface defintion cannot be generated correctly [due to MatInfo]
2800 
2801 .seealso: MatStashGetInfo()
2802 
2803 @*/
2804 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2805 {
2806   PetscErrorCode ierr;
2807 
2808   PetscFunctionBegin;
2809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2810   PetscValidType(mat,1);
2811   PetscValidPointer(info,3);
2812   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2813   MatCheckPreallocated(mat,1);
2814   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2815   PetscFunctionReturn(0);
2816 }
2817 
2818 /*
2819    This is used by external packages where it is not easy to get the info from the actual
2820    matrix factorization.
2821 */
2822 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2823 {
2824   PetscErrorCode ierr;
2825 
2826   PetscFunctionBegin;
2827   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2828   PetscFunctionReturn(0);
2829 }
2830 
2831 /* ----------------------------------------------------------*/
2832 
2833 /*@C
2834    MatLUFactor - Performs in-place LU factorization of matrix.
2835 
2836    Collective on Mat
2837 
2838    Input Parameters:
2839 +  mat - the matrix
2840 .  row - row permutation
2841 .  col - column permutation
2842 -  info - options for factorization, includes
2843 $          fill - expected fill as ratio of original fill.
2844 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2845 $                   Run with the option -info to determine an optimal value to use
2846 
2847    Notes:
2848    Most users should employ the simplified KSP interface for linear solvers
2849    instead of working directly with matrix algebra routines such as this.
2850    See, e.g., KSPCreate().
2851 
2852    This changes the state of the matrix to a factored matrix; it cannot be used
2853    for example with MatSetValues() unless one first calls MatSetUnfactored().
2854 
2855    Level: developer
2856 
2857 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2858           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2859 
2860     Developer Note: fortran interface is not autogenerated as the f90
2861     interface defintion cannot be generated correctly [due to MatFactorInfo]
2862 
2863 @*/
2864 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2865 {
2866   PetscErrorCode ierr;
2867   MatFactorInfo  tinfo;
2868 
2869   PetscFunctionBegin;
2870   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2871   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2872   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2873   if (info) PetscValidPointer(info,4);
2874   PetscValidType(mat,1);
2875   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2876   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2877   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2878   MatCheckPreallocated(mat,1);
2879   if (!info) {
2880     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2881     info = &tinfo;
2882   }
2883 
2884   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2885   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2886   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2887   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2888   PetscFunctionReturn(0);
2889 }
2890 
2891 /*@C
2892    MatILUFactor - Performs in-place ILU factorization of matrix.
2893 
2894    Collective on Mat
2895 
2896    Input Parameters:
2897 +  mat - the matrix
2898 .  row - row permutation
2899 .  col - column permutation
2900 -  info - structure containing
2901 $      levels - number of levels of fill.
2902 $      expected fill - as ratio of original fill.
2903 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2904                 missing diagonal entries)
2905 
2906    Notes:
2907    Probably really in-place only when level of fill is zero, otherwise allocates
2908    new space to store factored matrix and deletes previous memory.
2909 
2910    Most users should employ the simplified KSP interface for linear solvers
2911    instead of working directly with matrix algebra routines such as this.
2912    See, e.g., KSPCreate().
2913 
2914    Level: developer
2915 
2916 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2917 
2918     Developer Note: fortran interface is not autogenerated as the f90
2919     interface defintion cannot be generated correctly [due to MatFactorInfo]
2920 
2921 @*/
2922 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2923 {
2924   PetscErrorCode ierr;
2925 
2926   PetscFunctionBegin;
2927   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2928   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2929   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2930   PetscValidPointer(info,4);
2931   PetscValidType(mat,1);
2932   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2933   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2934   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2935   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2936   MatCheckPreallocated(mat,1);
2937 
2938   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2939   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2940   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2941   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2942   PetscFunctionReturn(0);
2943 }
2944 
2945 /*@C
2946    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2947    Call this routine before calling MatLUFactorNumeric().
2948 
2949    Collective on Mat
2950 
2951    Input Parameters:
2952 +  fact - the factor matrix obtained with MatGetFactor()
2953 .  mat - the matrix
2954 .  row, col - row and column permutations
2955 -  info - options for factorization, includes
2956 $          fill - expected fill as ratio of original fill.
2957 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2958 $                   Run with the option -info to determine an optimal value to use
2959 
2960 
2961    Notes:
2962     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2963 
2964    Most users should employ the simplified KSP interface for linear solvers
2965    instead of working directly with matrix algebra routines such as this.
2966    See, e.g., KSPCreate().
2967 
2968    Level: developer
2969 
2970 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2971 
2972     Developer Note: fortran interface is not autogenerated as the f90
2973     interface defintion cannot be generated correctly [due to MatFactorInfo]
2974 
2975 @*/
2976 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2977 {
2978   PetscErrorCode ierr;
2979   MatFactorInfo  tinfo;
2980 
2981   PetscFunctionBegin;
2982   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2983   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2984   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2985   if (info) PetscValidPointer(info,4);
2986   PetscValidType(mat,1);
2987   PetscValidPointer(fact,5);
2988   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2989   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2990   if (!(fact)->ops->lufactorsymbolic) {
2991     MatSolverType spackage;
2992     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
2993     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2994   }
2995   MatCheckPreallocated(mat,2);
2996   if (!info) {
2997     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2998     info = &tinfo;
2999   }
3000 
3001   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3002   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3003   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3004   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3005   PetscFunctionReturn(0);
3006 }
3007 
3008 /*@C
3009    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3010    Call this routine after first calling MatLUFactorSymbolic().
3011 
3012    Collective on Mat
3013 
3014    Input Parameters:
3015 +  fact - the factor matrix obtained with MatGetFactor()
3016 .  mat - the matrix
3017 -  info - options for factorization
3018 
3019    Notes:
3020    See MatLUFactor() for in-place factorization.  See
3021    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3022 
3023    Most users should employ the simplified KSP interface for linear solvers
3024    instead of working directly with matrix algebra routines such as this.
3025    See, e.g., KSPCreate().
3026 
3027    Level: developer
3028 
3029 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3030 
3031     Developer Note: fortran interface is not autogenerated as the f90
3032     interface defintion cannot be generated correctly [due to MatFactorInfo]
3033 
3034 @*/
3035 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3036 {
3037   MatFactorInfo  tinfo;
3038   PetscErrorCode ierr;
3039 
3040   PetscFunctionBegin;
3041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3042   PetscValidType(mat,1);
3043   PetscValidPointer(fact,2);
3044   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3045   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046   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);
3047 
3048   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3049   MatCheckPreallocated(mat,2);
3050   if (!info) {
3051     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3052     info = &tinfo;
3053   }
3054 
3055   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3056   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3057   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3058   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3059   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3060   PetscFunctionReturn(0);
3061 }
3062 
3063 /*@C
3064    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3065    symmetric matrix.
3066 
3067    Collective on Mat
3068 
3069    Input Parameters:
3070 +  mat - the matrix
3071 .  perm - row and column permutations
3072 -  f - expected fill as ratio of original fill
3073 
3074    Notes:
3075    See MatLUFactor() for the nonsymmetric case.  See also
3076    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3077 
3078    Most users should employ the simplified KSP interface for linear solvers
3079    instead of working directly with matrix algebra routines such as this.
3080    See, e.g., KSPCreate().
3081 
3082    Level: developer
3083 
3084 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3085           MatGetOrdering()
3086 
3087     Developer Note: fortran interface is not autogenerated as the f90
3088     interface defintion cannot be generated correctly [due to MatFactorInfo]
3089 
3090 @*/
3091 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3092 {
3093   PetscErrorCode ierr;
3094   MatFactorInfo  tinfo;
3095 
3096   PetscFunctionBegin;
3097   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3098   PetscValidType(mat,1);
3099   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3100   if (info) PetscValidPointer(info,3);
3101   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3102   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3103   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3104   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);
3105   MatCheckPreallocated(mat,1);
3106   if (!info) {
3107     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3108     info = &tinfo;
3109   }
3110 
3111   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3112   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3113   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3114   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3115   PetscFunctionReturn(0);
3116 }
3117 
3118 /*@C
3119    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3120    of a symmetric matrix.
3121 
3122    Collective on Mat
3123 
3124    Input Parameters:
3125 +  fact - the factor matrix obtained with MatGetFactor()
3126 .  mat - the matrix
3127 .  perm - row and column permutations
3128 -  info - options for factorization, includes
3129 $          fill - expected fill as ratio of original fill.
3130 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3131 $                   Run with the option -info to determine an optimal value to use
3132 
3133    Notes:
3134    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3135    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3136 
3137    Most users should employ the simplified KSP interface for linear solvers
3138    instead of working directly with matrix algebra routines such as this.
3139    See, e.g., KSPCreate().
3140 
3141    Level: developer
3142 
3143 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3144           MatGetOrdering()
3145 
3146     Developer Note: fortran interface is not autogenerated as the f90
3147     interface defintion cannot be generated correctly [due to MatFactorInfo]
3148 
3149 @*/
3150 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3151 {
3152   PetscErrorCode ierr;
3153   MatFactorInfo  tinfo;
3154 
3155   PetscFunctionBegin;
3156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3157   PetscValidType(mat,1);
3158   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3159   if (info) PetscValidPointer(info,3);
3160   PetscValidPointer(fact,4);
3161   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3162   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3163   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3164   if (!(fact)->ops->choleskyfactorsymbolic) {
3165     MatSolverType spackage;
3166     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3167     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3168   }
3169   MatCheckPreallocated(mat,2);
3170   if (!info) {
3171     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3172     info = &tinfo;
3173   }
3174 
3175   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3176   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3177   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3178   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3179   PetscFunctionReturn(0);
3180 }
3181 
3182 /*@C
3183    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3184    of a symmetric matrix. Call this routine after first calling
3185    MatCholeskyFactorSymbolic().
3186 
3187    Collective on Mat
3188 
3189    Input Parameters:
3190 +  fact - the factor matrix obtained with MatGetFactor()
3191 .  mat - the initial matrix
3192 .  info - options for factorization
3193 -  fact - the symbolic factor of mat
3194 
3195 
3196    Notes:
3197    Most users should employ the simplified KSP interface for linear solvers
3198    instead of working directly with matrix algebra routines such as this.
3199    See, e.g., KSPCreate().
3200 
3201    Level: developer
3202 
3203 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3204 
3205     Developer Note: fortran interface is not autogenerated as the f90
3206     interface defintion cannot be generated correctly [due to MatFactorInfo]
3207 
3208 @*/
3209 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3210 {
3211   MatFactorInfo  tinfo;
3212   PetscErrorCode ierr;
3213 
3214   PetscFunctionBegin;
3215   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3216   PetscValidType(mat,1);
3217   PetscValidPointer(fact,2);
3218   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3219   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3220   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3221   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);
3222   MatCheckPreallocated(mat,2);
3223   if (!info) {
3224     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3225     info = &tinfo;
3226   }
3227 
3228   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3229   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3230   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3231   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3232   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3233   PetscFunctionReturn(0);
3234 }
3235 
3236 /* ----------------------------------------------------------------*/
3237 /*@
3238    MatSolve - Solves A x = b, given a factored matrix.
3239 
3240    Neighbor-wise Collective on Mat
3241 
3242    Input Parameters:
3243 +  mat - the factored matrix
3244 -  b - the right-hand-side vector
3245 
3246    Output Parameter:
3247 .  x - the result vector
3248 
3249    Notes:
3250    The vectors b and x cannot be the same.  I.e., one cannot
3251    call MatSolve(A,x,x).
3252 
3253    Notes:
3254    Most users should employ the simplified KSP interface for linear solvers
3255    instead of working directly with matrix algebra routines such as this.
3256    See, e.g., KSPCreate().
3257 
3258    Level: developer
3259 
3260 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3261 @*/
3262 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3263 {
3264   PetscErrorCode ierr;
3265 
3266   PetscFunctionBegin;
3267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3268   PetscValidType(mat,1);
3269   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3270   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3271   PetscCheckSameComm(mat,1,b,2);
3272   PetscCheckSameComm(mat,1,x,3);
3273   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3274   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);
3275   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);
3276   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);
3277   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3278   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3279   MatCheckPreallocated(mat,1);
3280 
3281   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3282   if (mat->factorerrortype) {
3283     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3284     ierr = VecSetInf(x);CHKERRQ(ierr);
3285   } else {
3286     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3287     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3288   }
3289   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3290   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3291   PetscFunctionReturn(0);
3292 }
3293 
3294 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3295 {
3296   PetscErrorCode ierr;
3297   Vec            b,x;
3298   PetscInt       m,N,i;
3299   PetscScalar    *bb,*xx;
3300 
3301   PetscFunctionBegin;
3302   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3303   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3304   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3305   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3306   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3307   for (i=0; i<N; i++) {
3308     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3309     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3310     if (trans) {
3311       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3312     } else {
3313       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3314     }
3315     ierr = VecResetArray(x);CHKERRQ(ierr);
3316     ierr = VecResetArray(b);CHKERRQ(ierr);
3317   }
3318   ierr = VecDestroy(&b);CHKERRQ(ierr);
3319   ierr = VecDestroy(&x);CHKERRQ(ierr);
3320   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3321   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3322   PetscFunctionReturn(0);
3323 }
3324 
3325 /*@
3326    MatMatSolve - Solves A X = B, given a factored matrix.
3327 
3328    Neighbor-wise Collective on Mat
3329 
3330    Input Parameters:
3331 +  A - the factored matrix
3332 -  B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3333 
3334    Output Parameter:
3335 .  X - the result matrix (dense matrix)
3336 
3337    Notes:
3338    If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B);
3339    otherwise, B and X cannot be the same.
3340 
3341    Notes:
3342    Most users should usually employ the simplified KSP interface for linear solvers
3343    instead of working directly with matrix algebra routines such as this.
3344    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3345    at a time.
3346 
3347    Level: developer
3348 
3349 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3350 @*/
3351 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3352 {
3353   PetscErrorCode ierr;
3354 
3355   PetscFunctionBegin;
3356   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3357   PetscValidType(A,1);
3358   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3359   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3360   PetscCheckSameComm(A,1,B,2);
3361   PetscCheckSameComm(A,1,X,3);
3362   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);
3363   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);
3364   if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3365   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3366   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3367   MatCheckPreallocated(A,1);
3368 
3369   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3370   if (!A->ops->matsolve) {
3371     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3372     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3373   } else {
3374     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3375   }
3376   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3377   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3378   PetscFunctionReturn(0);
3379 }
3380 
3381 /*@
3382    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3383 
3384    Neighbor-wise Collective on Mat
3385 
3386    Input Parameters:
3387 +  A - the factored matrix
3388 -  B - the right-hand-side matrix  (dense matrix)
3389 
3390    Output Parameter:
3391 .  X - the result matrix (dense matrix)
3392 
3393    Notes:
3394    The matrices B and X cannot be the same.  I.e., one cannot
3395    call MatMatSolveTranspose(A,X,X).
3396 
3397    Notes:
3398    Most users should usually employ the simplified KSP interface for linear solvers
3399    instead of working directly with matrix algebra routines such as this.
3400    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3401    at a time.
3402 
3403    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3404 
3405    Level: developer
3406 
3407 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3408 @*/
3409 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3410 {
3411   PetscErrorCode ierr;
3412 
3413   PetscFunctionBegin;
3414   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3415   PetscValidType(A,1);
3416   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3417   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3418   PetscCheckSameComm(A,1,B,2);
3419   PetscCheckSameComm(A,1,X,3);
3420   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3421   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);
3422   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);
3423   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);
3424   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");
3425   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3426   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3427   MatCheckPreallocated(A,1);
3428 
3429   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3430   if (!A->ops->matsolvetranspose) {
3431     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3432     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3433   } else {
3434     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3435   }
3436   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3437   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3438   PetscFunctionReturn(0);
3439 }
3440 
3441 /*@
3442    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3443 
3444    Neighbor-wise Collective on Mat
3445 
3446    Input Parameters:
3447 +  A - the factored matrix
3448 -  Bt - the transpose of right-hand-side matrix
3449 
3450    Output Parameter:
3451 .  X - the result matrix (dense matrix)
3452 
3453    Notes:
3454    Most users should usually employ the simplified KSP interface for linear solvers
3455    instead of working directly with matrix algebra routines such as this.
3456    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3457    at a time.
3458 
3459    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().
3460 
3461    Level: developer
3462 
3463 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3464 @*/
3465 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3466 {
3467   PetscErrorCode ierr;
3468 
3469   PetscFunctionBegin;
3470   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3471   PetscValidType(A,1);
3472   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3473   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3474   PetscCheckSameComm(A,1,Bt,2);
3475   PetscCheckSameComm(A,1,X,3);
3476 
3477   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3478   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);
3479   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);
3480   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");
3481   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3482   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3483   MatCheckPreallocated(A,1);
3484 
3485   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3486   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3487   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3488   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3489   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3490   PetscFunctionReturn(0);
3491 }
3492 
3493 /*@
3494    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3495                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3496 
3497    Neighbor-wise Collective on Mat
3498 
3499    Input Parameters:
3500 +  mat - the factored matrix
3501 -  b - the right-hand-side vector
3502 
3503    Output Parameter:
3504 .  x - the result vector
3505 
3506    Notes:
3507    MatSolve() should be used for most applications, as it performs
3508    a forward solve followed by a backward solve.
3509 
3510    The vectors b and x cannot be the same,  i.e., one cannot
3511    call MatForwardSolve(A,x,x).
3512 
3513    For matrix in seqsbaij format with block size larger than 1,
3514    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3515    MatForwardSolve() solves U^T*D y = b, and
3516    MatBackwardSolve() solves U x = y.
3517    Thus they do not provide a symmetric preconditioner.
3518 
3519    Most users should employ the simplified KSP interface for linear solvers
3520    instead of working directly with matrix algebra routines such as this.
3521    See, e.g., KSPCreate().
3522 
3523    Level: developer
3524 
3525 .seealso: MatSolve(), MatBackwardSolve()
3526 @*/
3527 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3528 {
3529   PetscErrorCode ierr;
3530 
3531   PetscFunctionBegin;
3532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3533   PetscValidType(mat,1);
3534   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3535   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3536   PetscCheckSameComm(mat,1,b,2);
3537   PetscCheckSameComm(mat,1,x,3);
3538   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3539   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);
3540   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);
3541   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);
3542   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3543   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3544   MatCheckPreallocated(mat,1);
3545 
3546   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3547   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3548   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3549   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3550   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3551   PetscFunctionReturn(0);
3552 }
3553 
3554 /*@
3555    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3556                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3557 
3558    Neighbor-wise Collective on Mat
3559 
3560    Input Parameters:
3561 +  mat - the factored matrix
3562 -  b - the right-hand-side vector
3563 
3564    Output Parameter:
3565 .  x - the result vector
3566 
3567    Notes:
3568    MatSolve() should be used for most applications, as it performs
3569    a forward solve followed by a backward solve.
3570 
3571    The vectors b and x cannot be the same.  I.e., one cannot
3572    call MatBackwardSolve(A,x,x).
3573 
3574    For matrix in seqsbaij format with block size larger than 1,
3575    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3576    MatForwardSolve() solves U^T*D y = b, and
3577    MatBackwardSolve() solves U x = y.
3578    Thus they do not provide a symmetric preconditioner.
3579 
3580    Most users should employ the simplified KSP interface for linear solvers
3581    instead of working directly with matrix algebra routines such as this.
3582    See, e.g., KSPCreate().
3583 
3584    Level: developer
3585 
3586 .seealso: MatSolve(), MatForwardSolve()
3587 @*/
3588 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3589 {
3590   PetscErrorCode ierr;
3591 
3592   PetscFunctionBegin;
3593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3594   PetscValidType(mat,1);
3595   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3596   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3597   PetscCheckSameComm(mat,1,b,2);
3598   PetscCheckSameComm(mat,1,x,3);
3599   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3600   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);
3601   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);
3602   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);
3603   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3604   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3605   MatCheckPreallocated(mat,1);
3606 
3607   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3608   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3609   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3610   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3611   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3612   PetscFunctionReturn(0);
3613 }
3614 
3615 /*@
3616    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3617 
3618    Neighbor-wise Collective on Mat
3619 
3620    Input Parameters:
3621 +  mat - the factored matrix
3622 .  b - the right-hand-side vector
3623 -  y - the vector to be added to
3624 
3625    Output Parameter:
3626 .  x - the result vector
3627 
3628    Notes:
3629    The vectors b and x cannot be the same.  I.e., one cannot
3630    call MatSolveAdd(A,x,y,x).
3631 
3632    Most users should employ the simplified KSP interface for linear solvers
3633    instead of working directly with matrix algebra routines such as this.
3634    See, e.g., KSPCreate().
3635 
3636    Level: developer
3637 
3638 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3639 @*/
3640 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3641 {
3642   PetscScalar    one = 1.0;
3643   Vec            tmp;
3644   PetscErrorCode ierr;
3645 
3646   PetscFunctionBegin;
3647   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3648   PetscValidType(mat,1);
3649   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3650   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3651   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3652   PetscCheckSameComm(mat,1,b,2);
3653   PetscCheckSameComm(mat,1,y,2);
3654   PetscCheckSameComm(mat,1,x,3);
3655   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3656   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);
3657   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);
3658   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);
3659   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);
3660   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);
3661   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3662   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3663   MatCheckPreallocated(mat,1);
3664 
3665   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3666   if (mat->ops->solveadd) {
3667     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3668   } else {
3669     /* do the solve then the add manually */
3670     if (x != y) {
3671       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3672       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3673     } else {
3674       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3675       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3676       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3677       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3678       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3679       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3680     }
3681   }
3682   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3683   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3684   PetscFunctionReturn(0);
3685 }
3686 
3687 /*@
3688    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3689 
3690    Neighbor-wise Collective on Mat
3691 
3692    Input Parameters:
3693 +  mat - the factored matrix
3694 -  b - the right-hand-side vector
3695 
3696    Output Parameter:
3697 .  x - the result vector
3698 
3699    Notes:
3700    The vectors b and x cannot be the same.  I.e., one cannot
3701    call MatSolveTranspose(A,x,x).
3702 
3703    Most users should employ the simplified KSP interface for linear solvers
3704    instead of working directly with matrix algebra routines such as this.
3705    See, e.g., KSPCreate().
3706 
3707    Level: developer
3708 
3709 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3710 @*/
3711 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3712 {
3713   PetscErrorCode ierr;
3714 
3715   PetscFunctionBegin;
3716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3717   PetscValidType(mat,1);
3718   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3719   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3720   PetscCheckSameComm(mat,1,b,2);
3721   PetscCheckSameComm(mat,1,x,3);
3722   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3723   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);
3724   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);
3725   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3726   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3727   MatCheckPreallocated(mat,1);
3728   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3729   if (mat->factorerrortype) {
3730     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3731     ierr = VecSetInf(x);CHKERRQ(ierr);
3732   } else {
3733     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3734     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3735   }
3736   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3737   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3738   PetscFunctionReturn(0);
3739 }
3740 
3741 /*@
3742    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3743                       factored matrix.
3744 
3745    Neighbor-wise Collective on Mat
3746 
3747    Input Parameters:
3748 +  mat - the factored matrix
3749 .  b - the right-hand-side vector
3750 -  y - the vector to be added to
3751 
3752    Output Parameter:
3753 .  x - the result vector
3754 
3755    Notes:
3756    The vectors b and x cannot be the same.  I.e., one cannot
3757    call MatSolveTransposeAdd(A,x,y,x).
3758 
3759    Most users should employ the simplified KSP interface for linear solvers
3760    instead of working directly with matrix algebra routines such as this.
3761    See, e.g., KSPCreate().
3762 
3763    Level: developer
3764 
3765 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3766 @*/
3767 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3768 {
3769   PetscScalar    one = 1.0;
3770   PetscErrorCode ierr;
3771   Vec            tmp;
3772 
3773   PetscFunctionBegin;
3774   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3775   PetscValidType(mat,1);
3776   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3777   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3778   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3779   PetscCheckSameComm(mat,1,b,2);
3780   PetscCheckSameComm(mat,1,y,3);
3781   PetscCheckSameComm(mat,1,x,4);
3782   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3783   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);
3784   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);
3785   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);
3786   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);
3787   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3788   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3789   MatCheckPreallocated(mat,1);
3790 
3791   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3792   if (mat->ops->solvetransposeadd) {
3793     if (mat->factorerrortype) {
3794       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3795       ierr = VecSetInf(x);CHKERRQ(ierr);
3796     } else {
3797       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3798     }
3799   } else {
3800     /* do the solve then the add manually */
3801     if (x != y) {
3802       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3803       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3804     } else {
3805       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3806       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3807       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3808       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3809       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3810       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3811     }
3812   }
3813   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3814   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3815   PetscFunctionReturn(0);
3816 }
3817 /* ----------------------------------------------------------------*/
3818 
3819 /*@
3820    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3821 
3822    Neighbor-wise Collective on Mat
3823 
3824    Input Parameters:
3825 +  mat - the matrix
3826 .  b - the right hand side
3827 .  omega - the relaxation factor
3828 .  flag - flag indicating the type of SOR (see below)
3829 .  shift -  diagonal shift
3830 .  its - the number of iterations
3831 -  lits - the number of local iterations
3832 
3833    Output Parameters:
3834 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3835 
3836    SOR Flags:
3837 +     SOR_FORWARD_SWEEP - forward SOR
3838 .     SOR_BACKWARD_SWEEP - backward SOR
3839 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3840 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3841 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3842 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3843 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3844          upper/lower triangular part of matrix to
3845          vector (with omega)
3846 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
3847 
3848    Notes:
3849    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3850    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3851    on each processor.
3852 
3853    Application programmers will not generally use MatSOR() directly,
3854    but instead will employ the KSP/PC interface.
3855 
3856    Notes:
3857     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3858 
3859    Notes for Advanced Users:
3860    The flags are implemented as bitwise inclusive or operations.
3861    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3862    to specify a zero initial guess for SSOR.
3863 
3864    Most users should employ the simplified KSP interface for linear solvers
3865    instead of working directly with matrix algebra routines such as this.
3866    See, e.g., KSPCreate().
3867 
3868    Vectors x and b CANNOT be the same
3869 
3870    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3871 
3872    Level: developer
3873 
3874 @*/
3875 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3876 {
3877   PetscErrorCode ierr;
3878 
3879   PetscFunctionBegin;
3880   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3881   PetscValidType(mat,1);
3882   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3883   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3884   PetscCheckSameComm(mat,1,b,2);
3885   PetscCheckSameComm(mat,1,x,8);
3886   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3887   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3888   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3889   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);
3890   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);
3891   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);
3892   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3893   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3894   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3895 
3896   MatCheckPreallocated(mat,1);
3897   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3898   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3899   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3900   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3901   PetscFunctionReturn(0);
3902 }
3903 
3904 /*
3905       Default matrix copy routine.
3906 */
3907 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3908 {
3909   PetscErrorCode    ierr;
3910   PetscInt          i,rstart = 0,rend = 0,nz;
3911   const PetscInt    *cwork;
3912   const PetscScalar *vwork;
3913 
3914   PetscFunctionBegin;
3915   if (B->assembled) {
3916     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3917   }
3918   if (str == SAME_NONZERO_PATTERN) {
3919     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3920     for (i=rstart; i<rend; i++) {
3921       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3922       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3923       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3924     }
3925   } else {
3926     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
3927   }
3928   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3929   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3930   PetscFunctionReturn(0);
3931 }
3932 
3933 /*@
3934    MatCopy - Copies a matrix to another matrix.
3935 
3936    Collective on Mat
3937 
3938    Input Parameters:
3939 +  A - the matrix
3940 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3941 
3942    Output Parameter:
3943 .  B - where the copy is put
3944 
3945    Notes:
3946    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3947    same nonzero pattern or the routine will crash.
3948 
3949    MatCopy() copies the matrix entries of a matrix to another existing
3950    matrix (after first zeroing the second matrix).  A related routine is
3951    MatConvert(), which first creates a new matrix and then copies the data.
3952 
3953    Level: intermediate
3954 
3955 .seealso: MatConvert(), MatDuplicate()
3956 
3957 @*/
3958 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3959 {
3960   PetscErrorCode ierr;
3961   PetscInt       i;
3962 
3963   PetscFunctionBegin;
3964   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3965   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3966   PetscValidType(A,1);
3967   PetscValidType(B,2);
3968   PetscCheckSameComm(A,1,B,2);
3969   MatCheckPreallocated(B,2);
3970   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3971   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3972   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);
3973   MatCheckPreallocated(A,1);
3974   if (A == B) PetscFunctionReturn(0);
3975 
3976   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3977   if (A->ops->copy) {
3978     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3979   } else { /* generic conversion */
3980     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3981   }
3982 
3983   B->stencil.dim = A->stencil.dim;
3984   B->stencil.noc = A->stencil.noc;
3985   for (i=0; i<=A->stencil.dim; i++) {
3986     B->stencil.dims[i]   = A->stencil.dims[i];
3987     B->stencil.starts[i] = A->stencil.starts[i];
3988   }
3989 
3990   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3991   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3992   PetscFunctionReturn(0);
3993 }
3994 
3995 /*@C
3996    MatConvert - Converts a matrix to another matrix, either of the same
3997    or different type.
3998 
3999    Collective on Mat
4000 
4001    Input Parameters:
4002 +  mat - the matrix
4003 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4004    same type as the original matrix.
4005 -  reuse - denotes if the destination matrix is to be created or reused.
4006    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
4007    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).
4008 
4009    Output Parameter:
4010 .  M - pointer to place new matrix
4011 
4012    Notes:
4013    MatConvert() first creates a new matrix and then copies the data from
4014    the first matrix.  A related routine is MatCopy(), which copies the matrix
4015    entries of one matrix to another already existing matrix context.
4016 
4017    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4018    the MPI communicator of the generated matrix is always the same as the communicator
4019    of the input matrix.
4020 
4021    Level: intermediate
4022 
4023 .seealso: MatCopy(), MatDuplicate()
4024 @*/
4025 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4026 {
4027   PetscErrorCode ierr;
4028   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4029   char           convname[256],mtype[256];
4030   Mat            B;
4031 
4032   PetscFunctionBegin;
4033   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4034   PetscValidType(mat,1);
4035   PetscValidPointer(M,3);
4036   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4037   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4038   MatCheckPreallocated(mat,1);
4039 
4040   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4041   if (flg) newtype = mtype;
4042 
4043   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4044   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4045   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4046   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");
4047 
4048   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4049     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4050     PetscFunctionReturn(0);
4051   }
4052 
4053   /* Cache Mat options because some converter use MatHeaderReplace  */
4054   issymmetric = mat->symmetric;
4055   ishermitian = mat->hermitian;
4056 
4057   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4058     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4059     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4060   } else {
4061     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4062     const char     *prefix[3] = {"seq","mpi",""};
4063     PetscInt       i;
4064     /*
4065        Order of precedence:
4066        0) See if newtype is a superclass of the current matrix.
4067        1) See if a specialized converter is known to the current matrix.
4068        2) See if a specialized converter is known to the desired matrix class.
4069        3) See if a good general converter is registered for the desired class
4070           (as of 6/27/03 only MATMPIADJ falls into this category).
4071        4) See if a good general converter is known for the current matrix.
4072        5) Use a really basic converter.
4073     */
4074 
4075     /* 0) See if newtype is a superclass of the current matrix.
4076           i.e mat is mpiaij and newtype is aij */
4077     for (i=0; i<2; i++) {
4078       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4079       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4080       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4081       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4082       if (flg) {
4083         if (reuse == MAT_INPLACE_MATRIX) {
4084           PetscFunctionReturn(0);
4085         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4086           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4087           PetscFunctionReturn(0);
4088         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4089           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4090           PetscFunctionReturn(0);
4091         }
4092       }
4093     }
4094     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4095     for (i=0; i<3; i++) {
4096       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4097       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4098       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4099       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4100       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4101       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4102       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4103       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4104       if (conv) goto foundconv;
4105     }
4106 
4107     /* 2)  See if a specialized converter is known to the desired matrix class. */
4108     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4109     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4110     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4111     for (i=0; i<3; i++) {
4112       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4113       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4114       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4115       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4116       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4117       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4118       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4119       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4120       if (conv) {
4121         ierr = MatDestroy(&B);CHKERRQ(ierr);
4122         goto foundconv;
4123       }
4124     }
4125 
4126     /* 3) See if a good general converter is registered for the desired class */
4127     conv = B->ops->convertfrom;
4128     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4129     ierr = MatDestroy(&B);CHKERRQ(ierr);
4130     if (conv) goto foundconv;
4131 
4132     /* 4) See if a good general converter is known for the current matrix */
4133     if (mat->ops->convert) {
4134       conv = mat->ops->convert;
4135     }
4136     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4137     if (conv) goto foundconv;
4138 
4139     /* 5) Use a really basic converter. */
4140     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4141     conv = MatConvert_Basic;
4142 
4143 foundconv:
4144     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4145     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4146     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4147       /* the block sizes must be same if the mappings are copied over */
4148       (*M)->rmap->bs = mat->rmap->bs;
4149       (*M)->cmap->bs = mat->cmap->bs;
4150       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4151       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4152       (*M)->rmap->mapping = mat->rmap->mapping;
4153       (*M)->cmap->mapping = mat->cmap->mapping;
4154     }
4155     (*M)->stencil.dim = mat->stencil.dim;
4156     (*M)->stencil.noc = mat->stencil.noc;
4157     for (i=0; i<=mat->stencil.dim; i++) {
4158       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4159       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4160     }
4161     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4162   }
4163   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4164 
4165   /* Copy Mat options */
4166   if (issymmetric) {
4167     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4168   }
4169   if (ishermitian) {
4170     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4171   }
4172   PetscFunctionReturn(0);
4173 }
4174 
4175 /*@C
4176    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4177 
4178    Not Collective
4179 
4180    Input Parameter:
4181 .  mat - the matrix, must be a factored matrix
4182 
4183    Output Parameter:
4184 .   type - the string name of the package (do not free this string)
4185 
4186    Notes:
4187       In Fortran you pass in a empty string and the package name will be copied into it.
4188     (Make sure the string is long enough)
4189 
4190    Level: intermediate
4191 
4192 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4193 @*/
4194 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4195 {
4196   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4197 
4198   PetscFunctionBegin;
4199   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4200   PetscValidType(mat,1);
4201   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4202   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4203   if (!conv) {
4204     *type = MATSOLVERPETSC;
4205   } else {
4206     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4207   }
4208   PetscFunctionReturn(0);
4209 }
4210 
4211 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4212 struct _MatSolverTypeForSpecifcType {
4213   MatType                        mtype;
4214   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4215   MatSolverTypeForSpecifcType next;
4216 };
4217 
4218 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4219 struct _MatSolverTypeHolder {
4220   char                           *name;
4221   MatSolverTypeForSpecifcType handlers;
4222   MatSolverTypeHolder         next;
4223 };
4224 
4225 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4226 
4227 /*@C
4228    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4229 
4230    Input Parameters:
4231 +    package - name of the package, for example petsc or superlu
4232 .    mtype - the matrix type that works with this package
4233 .    ftype - the type of factorization supported by the package
4234 -    getfactor - routine that will create the factored matrix ready to be used
4235 
4236     Level: intermediate
4237 
4238 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4239 @*/
4240 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4241 {
4242   PetscErrorCode              ierr;
4243   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4244   PetscBool                   flg;
4245   MatSolverTypeForSpecifcType inext,iprev = NULL;
4246 
4247   PetscFunctionBegin;
4248   ierr = MatInitializePackage();CHKERRQ(ierr);
4249   if (!next) {
4250     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4251     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4252     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4253     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4254     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4255     PetscFunctionReturn(0);
4256   }
4257   while (next) {
4258     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4259     if (flg) {
4260       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4261       inext = next->handlers;
4262       while (inext) {
4263         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4264         if (flg) {
4265           inext->getfactor[(int)ftype-1] = getfactor;
4266           PetscFunctionReturn(0);
4267         }
4268         iprev = inext;
4269         inext = inext->next;
4270       }
4271       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4272       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4273       iprev->next->getfactor[(int)ftype-1] = getfactor;
4274       PetscFunctionReturn(0);
4275     }
4276     prev = next;
4277     next = next->next;
4278   }
4279   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4280   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4281   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4282   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4283   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4284   PetscFunctionReturn(0);
4285 }
4286 
4287 /*@C
4288    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4289 
4290    Input Parameters:
4291 +    package - name of the package, for example petsc or superlu
4292 .    ftype - the type of factorization supported by the package
4293 -    mtype - the matrix type that works with this package
4294 
4295    Output Parameters:
4296 +   foundpackage - PETSC_TRUE if the package was registered
4297 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4298 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4299 
4300     Level: intermediate
4301 
4302 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4303 @*/
4304 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4305 {
4306   PetscErrorCode                 ierr;
4307   MatSolverTypeHolder         next = MatSolverTypeHolders;
4308   PetscBool                      flg;
4309   MatSolverTypeForSpecifcType inext;
4310 
4311   PetscFunctionBegin;
4312   if (foundpackage) *foundpackage = PETSC_FALSE;
4313   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4314   if (getfactor)    *getfactor    = NULL;
4315 
4316   if (package) {
4317     while (next) {
4318       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4319       if (flg) {
4320         if (foundpackage) *foundpackage = PETSC_TRUE;
4321         inext = next->handlers;
4322         while (inext) {
4323           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4324           if (flg) {
4325             if (foundmtype) *foundmtype = PETSC_TRUE;
4326             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4327             PetscFunctionReturn(0);
4328           }
4329           inext = inext->next;
4330         }
4331       }
4332       next = next->next;
4333     }
4334   } else {
4335     while (next) {
4336       inext = next->handlers;
4337       while (inext) {
4338         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4339         if (flg && inext->getfactor[(int)ftype-1]) {
4340           if (foundpackage) *foundpackage = PETSC_TRUE;
4341           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4342           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4343           PetscFunctionReturn(0);
4344         }
4345         inext = inext->next;
4346       }
4347       next = next->next;
4348     }
4349   }
4350   PetscFunctionReturn(0);
4351 }
4352 
4353 PetscErrorCode MatSolverTypeDestroy(void)
4354 {
4355   PetscErrorCode              ierr;
4356   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4357   MatSolverTypeForSpecifcType inext,iprev;
4358 
4359   PetscFunctionBegin;
4360   while (next) {
4361     ierr = PetscFree(next->name);CHKERRQ(ierr);
4362     inext = next->handlers;
4363     while (inext) {
4364       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4365       iprev = inext;
4366       inext = inext->next;
4367       ierr = PetscFree(iprev);CHKERRQ(ierr);
4368     }
4369     prev = next;
4370     next = next->next;
4371     ierr = PetscFree(prev);CHKERRQ(ierr);
4372   }
4373   MatSolverTypeHolders = NULL;
4374   PetscFunctionReturn(0);
4375 }
4376 
4377 /*@C
4378    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4379 
4380    Collective on Mat
4381 
4382    Input Parameters:
4383 +  mat - the matrix
4384 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4385 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4386 
4387    Output Parameters:
4388 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4389 
4390    Notes:
4391       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4392      such as pastix, superlu, mumps etc.
4393 
4394       PETSc must have been ./configure to use the external solver, using the option --download-package
4395 
4396    Level: intermediate
4397 
4398 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4399 @*/
4400 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4401 {
4402   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4403   PetscBool      foundpackage,foundmtype;
4404 
4405   PetscFunctionBegin;
4406   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4407   PetscValidType(mat,1);
4408 
4409   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4410   MatCheckPreallocated(mat,1);
4411 
4412   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4413   if (!foundpackage) {
4414     if (type) {
4415       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4416     } else {
4417       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4418     }
4419   }
4420 
4421   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4422   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);
4423 
4424 #if defined(PETSC_USE_COMPLEX)
4425   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");
4426 #endif
4427 
4428   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4429   PetscFunctionReturn(0);
4430 }
4431 
4432 /*@C
4433    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4434 
4435    Not Collective
4436 
4437    Input Parameters:
4438 +  mat - the matrix
4439 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4440 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4441 
4442    Output Parameter:
4443 .    flg - PETSC_TRUE if the factorization is available
4444 
4445    Notes:
4446       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4447      such as pastix, superlu, mumps etc.
4448 
4449       PETSc must have been ./configure to use the external solver, using the option --download-package
4450 
4451    Level: intermediate
4452 
4453 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4454 @*/
4455 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4456 {
4457   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4458 
4459   PetscFunctionBegin;
4460   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4461   PetscValidType(mat,1);
4462 
4463   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4464   MatCheckPreallocated(mat,1);
4465 
4466   *flg = PETSC_FALSE;
4467   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4468   if (gconv) {
4469     *flg = PETSC_TRUE;
4470   }
4471   PetscFunctionReturn(0);
4472 }
4473 
4474 #include <petscdmtypes.h>
4475 
4476 /*@
4477    MatDuplicate - Duplicates a matrix including the non-zero structure.
4478 
4479    Collective on Mat
4480 
4481    Input Parameters:
4482 +  mat - the matrix
4483 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4484         See the manual page for MatDuplicateOption for an explanation of these options.
4485 
4486    Output Parameter:
4487 .  M - pointer to place new matrix
4488 
4489    Level: intermediate
4490 
4491    Notes:
4492     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4493     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.
4494 
4495 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4496 @*/
4497 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4498 {
4499   PetscErrorCode ierr;
4500   Mat            B;
4501   PetscInt       i;
4502   DM             dm;
4503   void           (*viewf)(void);
4504 
4505   PetscFunctionBegin;
4506   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4507   PetscValidType(mat,1);
4508   PetscValidPointer(M,3);
4509   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4510   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4511   MatCheckPreallocated(mat,1);
4512 
4513   *M = 0;
4514   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4515   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4516   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4517   B    = *M;
4518 
4519   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4520   if (viewf) {
4521     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4522   }
4523 
4524   B->stencil.dim = mat->stencil.dim;
4525   B->stencil.noc = mat->stencil.noc;
4526   for (i=0; i<=mat->stencil.dim; i++) {
4527     B->stencil.dims[i]   = mat->stencil.dims[i];
4528     B->stencil.starts[i] = mat->stencil.starts[i];
4529   }
4530 
4531   B->nooffproczerorows = mat->nooffproczerorows;
4532   B->nooffprocentries  = mat->nooffprocentries;
4533 
4534   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4535   if (dm) {
4536     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4537   }
4538   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4539   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4540   PetscFunctionReturn(0);
4541 }
4542 
4543 /*@
4544    MatGetDiagonal - Gets the diagonal of a matrix.
4545 
4546    Logically Collective on Mat
4547 
4548    Input Parameters:
4549 +  mat - the matrix
4550 -  v - the vector for storing the diagonal
4551 
4552    Output Parameter:
4553 .  v - the diagonal of the matrix
4554 
4555    Level: intermediate
4556 
4557    Note:
4558    Currently only correct in parallel for square matrices.
4559 
4560 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4561 @*/
4562 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4563 {
4564   PetscErrorCode ierr;
4565 
4566   PetscFunctionBegin;
4567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4568   PetscValidType(mat,1);
4569   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4570   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4571   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4572   MatCheckPreallocated(mat,1);
4573 
4574   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4575   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4576   PetscFunctionReturn(0);
4577 }
4578 
4579 /*@C
4580    MatGetRowMin - Gets the minimum value (of the real part) of each
4581         row of the matrix
4582 
4583    Logically Collective on Mat
4584 
4585    Input Parameters:
4586 .  mat - the matrix
4587 
4588    Output Parameter:
4589 +  v - the vector for storing the maximums
4590 -  idx - the indices of the column found for each row (optional)
4591 
4592    Level: intermediate
4593 
4594    Notes:
4595     The result of this call are the same as if one converted the matrix to dense format
4596       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4597 
4598     This code is only implemented for a couple of matrix formats.
4599 
4600 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4601           MatGetRowMax()
4602 @*/
4603 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4604 {
4605   PetscErrorCode ierr;
4606 
4607   PetscFunctionBegin;
4608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4609   PetscValidType(mat,1);
4610   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4611   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4612   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4613   MatCheckPreallocated(mat,1);
4614 
4615   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4616   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4617   PetscFunctionReturn(0);
4618 }
4619 
4620 /*@C
4621    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4622         row of the matrix
4623 
4624    Logically Collective on Mat
4625 
4626    Input Parameters:
4627 .  mat - the matrix
4628 
4629    Output Parameter:
4630 +  v - the vector for storing the minimums
4631 -  idx - the indices of the column found for each row (or NULL if not needed)
4632 
4633    Level: intermediate
4634 
4635    Notes:
4636     if a row is completely empty or has only 0.0 values then the idx[] value for that
4637     row is 0 (the first column).
4638 
4639     This code is only implemented for a couple of matrix formats.
4640 
4641 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4642 @*/
4643 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4644 {
4645   PetscErrorCode ierr;
4646 
4647   PetscFunctionBegin;
4648   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4649   PetscValidType(mat,1);
4650   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4651   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4652   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4653   MatCheckPreallocated(mat,1);
4654   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4655 
4656   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4657   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4658   PetscFunctionReturn(0);
4659 }
4660 
4661 /*@C
4662    MatGetRowMax - Gets the maximum value (of the real part) of each
4663         row of the matrix
4664 
4665    Logically Collective on Mat
4666 
4667    Input Parameters:
4668 .  mat - the matrix
4669 
4670    Output Parameter:
4671 +  v - the vector for storing the maximums
4672 -  idx - the indices of the column found for each row (optional)
4673 
4674    Level: intermediate
4675 
4676    Notes:
4677     The result of this call are the same as if one converted the matrix to dense format
4678       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4679 
4680     This code is only implemented for a couple of matrix formats.
4681 
4682 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4683 @*/
4684 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4685 {
4686   PetscErrorCode ierr;
4687 
4688   PetscFunctionBegin;
4689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4690   PetscValidType(mat,1);
4691   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4692   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4693   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4694   MatCheckPreallocated(mat,1);
4695 
4696   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4697   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4698   PetscFunctionReturn(0);
4699 }
4700 
4701 /*@C
4702    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4703         row of the matrix
4704 
4705    Logically Collective on Mat
4706 
4707    Input Parameters:
4708 .  mat - the matrix
4709 
4710    Output Parameter:
4711 +  v - the vector for storing the maximums
4712 -  idx - the indices of the column found for each row (or NULL if not needed)
4713 
4714    Level: intermediate
4715 
4716    Notes:
4717     if a row is completely empty or has only 0.0 values then the idx[] value for that
4718     row is 0 (the first column).
4719 
4720     This code is only implemented for a couple of matrix formats.
4721 
4722 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4723 @*/
4724 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4725 {
4726   PetscErrorCode ierr;
4727 
4728   PetscFunctionBegin;
4729   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4730   PetscValidType(mat,1);
4731   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4732   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4733   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4734   MatCheckPreallocated(mat,1);
4735   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4736 
4737   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4738   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4739   PetscFunctionReturn(0);
4740 }
4741 
4742 /*@
4743    MatGetRowSum - Gets the sum of each row of the matrix
4744 
4745    Logically or Neighborhood Collective on Mat
4746 
4747    Input Parameters:
4748 .  mat - the matrix
4749 
4750    Output Parameter:
4751 .  v - the vector for storing the sum of rows
4752 
4753    Level: intermediate
4754 
4755    Notes:
4756     This code is slow since it is not currently specialized for different formats
4757 
4758 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4759 @*/
4760 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4761 {
4762   Vec            ones;
4763   PetscErrorCode ierr;
4764 
4765   PetscFunctionBegin;
4766   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4767   PetscValidType(mat,1);
4768   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4769   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4770   MatCheckPreallocated(mat,1);
4771   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4772   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4773   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4774   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4775   PetscFunctionReturn(0);
4776 }
4777 
4778 /*@
4779    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4780 
4781    Collective on Mat
4782 
4783    Input Parameter:
4784 +  mat - the matrix to transpose
4785 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4786 
4787    Output Parameters:
4788 .  B - the transpose
4789 
4790    Notes:
4791      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4792 
4793      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4794 
4795      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4796 
4797    Level: intermediate
4798 
4799 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4800 @*/
4801 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4802 {
4803   PetscErrorCode ierr;
4804 
4805   PetscFunctionBegin;
4806   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4807   PetscValidType(mat,1);
4808   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4809   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4810   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4811   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4812   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4813   MatCheckPreallocated(mat,1);
4814 
4815   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4816   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4817   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4818   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4819   PetscFunctionReturn(0);
4820 }
4821 
4822 /*@
4823    MatIsTranspose - Test whether a matrix is another one's transpose,
4824         or its own, in which case it tests symmetry.
4825 
4826    Collective on Mat
4827 
4828    Input Parameter:
4829 +  A - the matrix to test
4830 -  B - the matrix to test against, this can equal the first parameter
4831 
4832    Output Parameters:
4833 .  flg - the result
4834 
4835    Notes:
4836    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4837    has a running time of the order of the number of nonzeros; the parallel
4838    test involves parallel copies of the block-offdiagonal parts of the matrix.
4839 
4840    Level: intermediate
4841 
4842 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4843 @*/
4844 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4845 {
4846   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4847 
4848   PetscFunctionBegin;
4849   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4850   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4851   PetscValidBoolPointer(flg,3);
4852   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4853   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4854   *flg = PETSC_FALSE;
4855   if (f && g) {
4856     if (f == g) {
4857       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4858     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4859   } else {
4860     MatType mattype;
4861     if (!f) {
4862       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4863     } else {
4864       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4865     }
4866     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4867   }
4868   PetscFunctionReturn(0);
4869 }
4870 
4871 /*@
4872    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4873 
4874    Collective on Mat
4875 
4876    Input Parameter:
4877 +  mat - the matrix to transpose and complex conjugate
4878 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4879 
4880    Output Parameters:
4881 .  B - the Hermitian
4882 
4883    Level: intermediate
4884 
4885 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4886 @*/
4887 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4888 {
4889   PetscErrorCode ierr;
4890 
4891   PetscFunctionBegin;
4892   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4893 #if defined(PETSC_USE_COMPLEX)
4894   ierr = MatConjugate(*B);CHKERRQ(ierr);
4895 #endif
4896   PetscFunctionReturn(0);
4897 }
4898 
4899 /*@
4900    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4901 
4902    Collective on Mat
4903 
4904    Input Parameter:
4905 +  A - the matrix to test
4906 -  B - the matrix to test against, this can equal the first parameter
4907 
4908    Output Parameters:
4909 .  flg - the result
4910 
4911    Notes:
4912    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4913    has a running time of the order of the number of nonzeros; the parallel
4914    test involves parallel copies of the block-offdiagonal parts of the matrix.
4915 
4916    Level: intermediate
4917 
4918 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4919 @*/
4920 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4921 {
4922   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4923 
4924   PetscFunctionBegin;
4925   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4926   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4927   PetscValidBoolPointer(flg,3);
4928   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4929   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4930   if (f && g) {
4931     if (f==g) {
4932       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4933     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4934   }
4935   PetscFunctionReturn(0);
4936 }
4937 
4938 /*@
4939    MatPermute - Creates a new matrix with rows and columns permuted from the
4940    original.
4941 
4942    Collective on Mat
4943 
4944    Input Parameters:
4945 +  mat - the matrix to permute
4946 .  row - row permutation, each processor supplies only the permutation for its rows
4947 -  col - column permutation, each processor supplies only the permutation for its columns
4948 
4949    Output Parameters:
4950 .  B - the permuted matrix
4951 
4952    Level: advanced
4953 
4954    Note:
4955    The index sets map from row/col of permuted matrix to row/col of original matrix.
4956    The index sets should be on the same communicator as Mat and have the same local sizes.
4957 
4958 .seealso: MatGetOrdering(), ISAllGather()
4959 
4960 @*/
4961 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4962 {
4963   PetscErrorCode ierr;
4964 
4965   PetscFunctionBegin;
4966   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4967   PetscValidType(mat,1);
4968   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4969   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4970   PetscValidPointer(B,4);
4971   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4972   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4973   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4974   MatCheckPreallocated(mat,1);
4975 
4976   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4977   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4978   PetscFunctionReturn(0);
4979 }
4980 
4981 /*@
4982    MatEqual - Compares two matrices.
4983 
4984    Collective on Mat
4985 
4986    Input Parameters:
4987 +  A - the first matrix
4988 -  B - the second matrix
4989 
4990    Output Parameter:
4991 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4992 
4993    Level: intermediate
4994 
4995 @*/
4996 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4997 {
4998   PetscErrorCode ierr;
4999 
5000   PetscFunctionBegin;
5001   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5002   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5003   PetscValidType(A,1);
5004   PetscValidType(B,2);
5005   PetscValidBoolPointer(flg,3);
5006   PetscCheckSameComm(A,1,B,2);
5007   MatCheckPreallocated(B,2);
5008   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5009   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5010   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);
5011   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5012   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5013   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);
5014   MatCheckPreallocated(A,1);
5015 
5016   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5017   PetscFunctionReturn(0);
5018 }
5019 
5020 /*@
5021    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5022    matrices that are stored as vectors.  Either of the two scaling
5023    matrices can be NULL.
5024 
5025    Collective on Mat
5026 
5027    Input Parameters:
5028 +  mat - the matrix to be scaled
5029 .  l - the left scaling vector (or NULL)
5030 -  r - the right scaling vector (or NULL)
5031 
5032    Notes:
5033    MatDiagonalScale() computes A = LAR, where
5034    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5035    The L scales the rows of the matrix, the R scales the columns of the matrix.
5036 
5037    Level: intermediate
5038 
5039 
5040 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5041 @*/
5042 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5043 {
5044   PetscErrorCode ierr;
5045 
5046   PetscFunctionBegin;
5047   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5048   PetscValidType(mat,1);
5049   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5050   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5051   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5052   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5053   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5054   MatCheckPreallocated(mat,1);
5055 
5056   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5057   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5058   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5059   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5060   PetscFunctionReturn(0);
5061 }
5062 
5063 /*@
5064     MatScale - Scales all elements of a matrix by a given number.
5065 
5066     Logically Collective on Mat
5067 
5068     Input Parameters:
5069 +   mat - the matrix to be scaled
5070 -   a  - the scaling value
5071 
5072     Output Parameter:
5073 .   mat - the scaled matrix
5074 
5075     Level: intermediate
5076 
5077 .seealso: MatDiagonalScale()
5078 @*/
5079 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5080 {
5081   PetscErrorCode ierr;
5082 
5083   PetscFunctionBegin;
5084   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5085   PetscValidType(mat,1);
5086   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5087   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5088   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5089   PetscValidLogicalCollectiveScalar(mat,a,2);
5090   MatCheckPreallocated(mat,1);
5091 
5092   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5093   if (a != (PetscScalar)1.0) {
5094     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5095     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5096   }
5097   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5098   PetscFunctionReturn(0);
5099 }
5100 
5101 /*@
5102    MatNorm - Calculates various norms of a matrix.
5103 
5104    Collective on Mat
5105 
5106    Input Parameters:
5107 +  mat - the matrix
5108 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5109 
5110    Output Parameters:
5111 .  nrm - the resulting norm
5112 
5113    Level: intermediate
5114 
5115 @*/
5116 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5117 {
5118   PetscErrorCode ierr;
5119 
5120   PetscFunctionBegin;
5121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5122   PetscValidType(mat,1);
5123   PetscValidScalarPointer(nrm,3);
5124 
5125   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5126   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5127   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5128   MatCheckPreallocated(mat,1);
5129 
5130   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5131   PetscFunctionReturn(0);
5132 }
5133 
5134 /*
5135      This variable is used to prevent counting of MatAssemblyBegin() that
5136    are called from within a MatAssemblyEnd().
5137 */
5138 static PetscInt MatAssemblyEnd_InUse = 0;
5139 /*@
5140    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5141    be called after completing all calls to MatSetValues().
5142 
5143    Collective on Mat
5144 
5145    Input Parameters:
5146 +  mat - the matrix
5147 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5148 
5149    Notes:
5150    MatSetValues() generally caches the values.  The matrix is ready to
5151    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5152    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5153    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5154    using the matrix.
5155 
5156    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5157    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
5158    a global collective operation requring all processes that share the matrix.
5159 
5160    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5161    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5162    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5163 
5164    Level: beginner
5165 
5166 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5167 @*/
5168 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5169 {
5170   PetscErrorCode ierr;
5171 
5172   PetscFunctionBegin;
5173   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5174   PetscValidType(mat,1);
5175   MatCheckPreallocated(mat,1);
5176   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5177   if (mat->assembled) {
5178     mat->was_assembled = PETSC_TRUE;
5179     mat->assembled     = PETSC_FALSE;
5180   }
5181 
5182   if (!MatAssemblyEnd_InUse) {
5183     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5184     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5185     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5186   } else if (mat->ops->assemblybegin) {
5187     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5188   }
5189   PetscFunctionReturn(0);
5190 }
5191 
5192 /*@
5193    MatAssembled - Indicates if a matrix has been assembled and is ready for
5194      use; for example, in matrix-vector product.
5195 
5196    Not Collective
5197 
5198    Input Parameter:
5199 .  mat - the matrix
5200 
5201    Output Parameter:
5202 .  assembled - PETSC_TRUE or PETSC_FALSE
5203 
5204    Level: advanced
5205 
5206 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5207 @*/
5208 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5209 {
5210   PetscFunctionBegin;
5211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5212   PetscValidPointer(assembled,2);
5213   *assembled = mat->assembled;
5214   PetscFunctionReturn(0);
5215 }
5216 
5217 /*@
5218    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5219    be called after MatAssemblyBegin().
5220 
5221    Collective on Mat
5222 
5223    Input Parameters:
5224 +  mat - the matrix
5225 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5226 
5227    Options Database Keys:
5228 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5229 .  -mat_view ::ascii_info_detail - Prints more detailed info
5230 .  -mat_view - Prints matrix in ASCII format
5231 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5232 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5233 .  -display <name> - Sets display name (default is host)
5234 .  -draw_pause <sec> - Sets number of seconds to pause after display
5235 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5236 .  -viewer_socket_machine <machine> - Machine to use for socket
5237 .  -viewer_socket_port <port> - Port number to use for socket
5238 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5239 
5240    Notes:
5241    MatSetValues() generally caches the values.  The matrix is ready to
5242    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5243    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5244    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5245    using the matrix.
5246 
5247    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5248    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5249    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5250 
5251    Level: beginner
5252 
5253 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5254 @*/
5255 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5256 {
5257   PetscErrorCode  ierr;
5258   static PetscInt inassm = 0;
5259   PetscBool       flg    = PETSC_FALSE;
5260 
5261   PetscFunctionBegin;
5262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5263   PetscValidType(mat,1);
5264 
5265   inassm++;
5266   MatAssemblyEnd_InUse++;
5267   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5268     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5269     if (mat->ops->assemblyend) {
5270       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5271     }
5272     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5273   } else if (mat->ops->assemblyend) {
5274     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5275   }
5276 
5277   /* Flush assembly is not a true assembly */
5278   if (type != MAT_FLUSH_ASSEMBLY) {
5279     mat->num_ass++;
5280     mat->assembled        = PETSC_TRUE;
5281     mat->ass_nonzerostate = mat->nonzerostate;
5282   }
5283 
5284   mat->insertmode = NOT_SET_VALUES;
5285   MatAssemblyEnd_InUse--;
5286   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5287   if (!mat->symmetric_eternal) {
5288     mat->symmetric_set              = PETSC_FALSE;
5289     mat->hermitian_set              = PETSC_FALSE;
5290     mat->structurally_symmetric_set = PETSC_FALSE;
5291   }
5292   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5293     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5294 
5295     if (mat->checksymmetryonassembly) {
5296       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5297       if (flg) {
5298         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5299       } else {
5300         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5301       }
5302     }
5303     if (mat->nullsp && mat->checknullspaceonassembly) {
5304       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5305     }
5306   }
5307   inassm--;
5308   PetscFunctionReturn(0);
5309 }
5310 
5311 /*@
5312    MatSetOption - Sets a parameter option for a matrix. Some options
5313    may be specific to certain storage formats.  Some options
5314    determine how values will be inserted (or added). Sorted,
5315    row-oriented input will generally assemble the fastest. The default
5316    is row-oriented.
5317 
5318    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5319 
5320    Input Parameters:
5321 +  mat - the matrix
5322 .  option - the option, one of those listed below (and possibly others),
5323 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5324 
5325   Options Describing Matrix Structure:
5326 +    MAT_SPD - symmetric positive definite
5327 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5328 .    MAT_HERMITIAN - transpose is the complex conjugation
5329 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5330 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5331                             you set to be kept with all future use of the matrix
5332                             including after MatAssemblyBegin/End() which could
5333                             potentially change the symmetry structure, i.e. you
5334                             KNOW the matrix will ALWAYS have the property you set.
5335 
5336 
5337    Options For Use with MatSetValues():
5338    Insert a logically dense subblock, which can be
5339 .    MAT_ROW_ORIENTED - row-oriented (default)
5340 
5341    Note these options reflect the data you pass in with MatSetValues(); it has
5342    nothing to do with how the data is stored internally in the matrix
5343    data structure.
5344 
5345    When (re)assembling a matrix, we can restrict the input for
5346    efficiency/debugging purposes.  These options include:
5347 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5348 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5349 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5350 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5351 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5352 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5353         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5354         performance for very large process counts.
5355 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5356         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5357         functions, instead sending only neighbor messages.
5358 
5359    Notes:
5360    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5361 
5362    Some options are relevant only for particular matrix types and
5363    are thus ignored by others.  Other options are not supported by
5364    certain matrix types and will generate an error message if set.
5365 
5366    If using a Fortran 77 module to compute a matrix, one may need to
5367    use the column-oriented option (or convert to the row-oriented
5368    format).
5369 
5370    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5371    that would generate a new entry in the nonzero structure is instead
5372    ignored.  Thus, if memory has not alredy been allocated for this particular
5373    data, then the insertion is ignored. For dense matrices, in which
5374    the entire array is allocated, no entries are ever ignored.
5375    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5376 
5377    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5378    that would generate a new entry in the nonzero structure instead produces
5379    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
5380 
5381    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5382    that would generate a new entry that has not been preallocated will
5383    instead produce an error. (Currently supported for AIJ and BAIJ formats
5384    only.) This is a useful flag when debugging matrix memory preallocation.
5385    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5386 
5387    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5388    other processors should be dropped, rather than stashed.
5389    This is useful if you know that the "owning" processor is also
5390    always generating the correct matrix entries, so that PETSc need
5391    not transfer duplicate entries generated on another processor.
5392 
5393    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5394    searches during matrix assembly. When this flag is set, the hash table
5395    is created during the first Matrix Assembly. This hash table is
5396    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5397    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5398    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5399    supported by MATMPIBAIJ format only.
5400 
5401    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5402    are kept in the nonzero structure
5403 
5404    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5405    a zero location in the matrix
5406 
5407    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5408 
5409    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5410         zero row routines and thus improves performance for very large process counts.
5411 
5412    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5413         part of the matrix (since they should match the upper triangular part).
5414 
5415    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5416                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5417                      with finite difference schemes with non-periodic boundary conditions.
5418    Notes:
5419     Can only be called after MatSetSizes() and MatSetType() have been set.
5420 
5421    Level: intermediate
5422 
5423 .seealso:  MatOption, Mat
5424 
5425 @*/
5426 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5427 {
5428   PetscErrorCode ierr;
5429 
5430   PetscFunctionBegin;
5431   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5432   PetscValidType(mat,1);
5433   if (op > 0) {
5434     PetscValidLogicalCollectiveEnum(mat,op,2);
5435     PetscValidLogicalCollectiveBool(mat,flg,3);
5436   }
5437 
5438   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);
5439   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()");
5440 
5441   switch (op) {
5442   case MAT_NO_OFF_PROC_ENTRIES:
5443     mat->nooffprocentries = flg;
5444     PetscFunctionReturn(0);
5445     break;
5446   case MAT_SUBSET_OFF_PROC_ENTRIES:
5447     mat->assembly_subset = flg;
5448     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5449 #if !defined(PETSC_HAVE_MPIUNI)
5450       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5451 #endif
5452       mat->stash.first_assembly_done = PETSC_FALSE;
5453     }
5454     PetscFunctionReturn(0);
5455   case MAT_NO_OFF_PROC_ZERO_ROWS:
5456     mat->nooffproczerorows = flg;
5457     PetscFunctionReturn(0);
5458     break;
5459   case MAT_SPD:
5460     mat->spd_set = PETSC_TRUE;
5461     mat->spd     = flg;
5462     if (flg) {
5463       mat->symmetric                  = PETSC_TRUE;
5464       mat->structurally_symmetric     = PETSC_TRUE;
5465       mat->symmetric_set              = PETSC_TRUE;
5466       mat->structurally_symmetric_set = PETSC_TRUE;
5467     }
5468     break;
5469   case MAT_SYMMETRIC:
5470     mat->symmetric = flg;
5471     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5472     mat->symmetric_set              = PETSC_TRUE;
5473     mat->structurally_symmetric_set = flg;
5474 #if !defined(PETSC_USE_COMPLEX)
5475     mat->hermitian     = flg;
5476     mat->hermitian_set = PETSC_TRUE;
5477 #endif
5478     break;
5479   case MAT_HERMITIAN:
5480     mat->hermitian = flg;
5481     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5482     mat->hermitian_set              = PETSC_TRUE;
5483     mat->structurally_symmetric_set = flg;
5484 #if !defined(PETSC_USE_COMPLEX)
5485     mat->symmetric     = flg;
5486     mat->symmetric_set = PETSC_TRUE;
5487 #endif
5488     break;
5489   case MAT_STRUCTURALLY_SYMMETRIC:
5490     mat->structurally_symmetric     = flg;
5491     mat->structurally_symmetric_set = PETSC_TRUE;
5492     break;
5493   case MAT_SYMMETRY_ETERNAL:
5494     mat->symmetric_eternal = flg;
5495     break;
5496   case MAT_STRUCTURE_ONLY:
5497     mat->structure_only = flg;
5498     break;
5499   case MAT_SORTED_FULL:
5500     mat->sortedfull = flg;
5501     break;
5502   default:
5503     break;
5504   }
5505   if (mat->ops->setoption) {
5506     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5507   }
5508   PetscFunctionReturn(0);
5509 }
5510 
5511 /*@
5512    MatGetOption - Gets a parameter option that has been set for a matrix.
5513 
5514    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5515 
5516    Input Parameters:
5517 +  mat - the matrix
5518 -  option - the option, this only responds to certain options, check the code for which ones
5519 
5520    Output Parameter:
5521 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5522 
5523     Notes:
5524     Can only be called after MatSetSizes() and MatSetType() have been set.
5525 
5526    Level: intermediate
5527 
5528 .seealso:  MatOption, MatSetOption()
5529 
5530 @*/
5531 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5532 {
5533   PetscFunctionBegin;
5534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5535   PetscValidType(mat,1);
5536 
5537   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);
5538   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()");
5539 
5540   switch (op) {
5541   case MAT_NO_OFF_PROC_ENTRIES:
5542     *flg = mat->nooffprocentries;
5543     break;
5544   case MAT_NO_OFF_PROC_ZERO_ROWS:
5545     *flg = mat->nooffproczerorows;
5546     break;
5547   case MAT_SYMMETRIC:
5548     *flg = mat->symmetric;
5549     break;
5550   case MAT_HERMITIAN:
5551     *flg = mat->hermitian;
5552     break;
5553   case MAT_STRUCTURALLY_SYMMETRIC:
5554     *flg = mat->structurally_symmetric;
5555     break;
5556   case MAT_SYMMETRY_ETERNAL:
5557     *flg = mat->symmetric_eternal;
5558     break;
5559   case MAT_SPD:
5560     *flg = mat->spd;
5561     break;
5562   default:
5563     break;
5564   }
5565   PetscFunctionReturn(0);
5566 }
5567 
5568 /*@
5569    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5570    this routine retains the old nonzero structure.
5571 
5572    Logically Collective on Mat
5573 
5574    Input Parameters:
5575 .  mat - the matrix
5576 
5577    Level: intermediate
5578 
5579    Notes:
5580     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.
5581    See the Performance chapter of the users manual for information on preallocating matrices.
5582 
5583 .seealso: MatZeroRows()
5584 @*/
5585 PetscErrorCode MatZeroEntries(Mat mat)
5586 {
5587   PetscErrorCode ierr;
5588 
5589   PetscFunctionBegin;
5590   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5591   PetscValidType(mat,1);
5592   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5593   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");
5594   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5595   MatCheckPreallocated(mat,1);
5596 
5597   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5598   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5599   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5600   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5601   PetscFunctionReturn(0);
5602 }
5603 
5604 /*@
5605    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5606    of a set of rows and columns of a matrix.
5607 
5608    Collective on Mat
5609 
5610    Input Parameters:
5611 +  mat - the matrix
5612 .  numRows - the number of rows to remove
5613 .  rows - the global row indices
5614 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5615 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5616 -  b - optional vector of right hand side, that will be adjusted by provided solution
5617 
5618    Notes:
5619    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5620 
5621    The user can set a value in the diagonal entry (or for the AIJ and
5622    row formats can optionally remove the main diagonal entry from the
5623    nonzero structure as well, by passing 0.0 as the final argument).
5624 
5625    For the parallel case, all processes that share the matrix (i.e.,
5626    those in the communicator used for matrix creation) MUST call this
5627    routine, regardless of whether any rows being zeroed are owned by
5628    them.
5629 
5630    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5631    list only rows local to itself).
5632 
5633    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5634 
5635    Level: intermediate
5636 
5637 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5638           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5639 @*/
5640 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5641 {
5642   PetscErrorCode ierr;
5643 
5644   PetscFunctionBegin;
5645   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5646   PetscValidType(mat,1);
5647   if (numRows) PetscValidIntPointer(rows,3);
5648   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5649   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5650   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5651   MatCheckPreallocated(mat,1);
5652 
5653   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5654   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5655   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5656   PetscFunctionReturn(0);
5657 }
5658 
5659 /*@
5660    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5661    of a set of rows and columns of a matrix.
5662 
5663    Collective on Mat
5664 
5665    Input Parameters:
5666 +  mat - the matrix
5667 .  is - the rows to zero
5668 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5669 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5670 -  b - optional vector of right hand side, that will be adjusted by provided solution
5671 
5672    Notes:
5673    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5674 
5675    The user can set a value in the diagonal entry (or for the AIJ and
5676    row formats can optionally remove the main diagonal entry from the
5677    nonzero structure as well, by passing 0.0 as the final argument).
5678 
5679    For the parallel case, all processes that share the matrix (i.e.,
5680    those in the communicator used for matrix creation) MUST call this
5681    routine, regardless of whether any rows being zeroed are owned by
5682    them.
5683 
5684    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5685    list only rows local to itself).
5686 
5687    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5688 
5689    Level: intermediate
5690 
5691 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5692           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5693 @*/
5694 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5695 {
5696   PetscErrorCode ierr;
5697   PetscInt       numRows;
5698   const PetscInt *rows;
5699 
5700   PetscFunctionBegin;
5701   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5702   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5703   PetscValidType(mat,1);
5704   PetscValidType(is,2);
5705   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5706   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5707   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5708   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5709   PetscFunctionReturn(0);
5710 }
5711 
5712 /*@
5713    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5714    of a set of rows of a matrix.
5715 
5716    Collective on Mat
5717 
5718    Input Parameters:
5719 +  mat - the matrix
5720 .  numRows - the number of rows to remove
5721 .  rows - the global row indices
5722 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5723 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5724 -  b - optional vector of right hand side, that will be adjusted by provided solution
5725 
5726    Notes:
5727    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5728    but does not release memory.  For the dense and block diagonal
5729    formats this does not alter the nonzero structure.
5730 
5731    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5732    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5733    merely zeroed.
5734 
5735    The user can set a value in the diagonal entry (or for the AIJ and
5736    row formats can optionally remove the main diagonal entry from the
5737    nonzero structure as well, by passing 0.0 as the final argument).
5738 
5739    For the parallel case, all processes that share the matrix (i.e.,
5740    those in the communicator used for matrix creation) MUST call this
5741    routine, regardless of whether any rows being zeroed are owned by
5742    them.
5743 
5744    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5745    list only rows local to itself).
5746 
5747    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5748    owns that are to be zeroed. This saves a global synchronization in the implementation.
5749 
5750    Level: intermediate
5751 
5752 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5753           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5754 @*/
5755 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5756 {
5757   PetscErrorCode ierr;
5758 
5759   PetscFunctionBegin;
5760   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5761   PetscValidType(mat,1);
5762   if (numRows) PetscValidIntPointer(rows,3);
5763   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5764   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5765   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5766   MatCheckPreallocated(mat,1);
5767 
5768   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5769   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5770   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5771   PetscFunctionReturn(0);
5772 }
5773 
5774 /*@
5775    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5776    of a set of rows of a matrix.
5777 
5778    Collective on Mat
5779 
5780    Input Parameters:
5781 +  mat - the matrix
5782 .  is - index set of rows to remove
5783 .  diag - value put in all diagonals of eliminated rows
5784 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5785 -  b - optional vector of right hand side, that will be adjusted by provided solution
5786 
5787    Notes:
5788    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5789    but does not release memory.  For the dense and block diagonal
5790    formats this does not alter the nonzero structure.
5791 
5792    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5793    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5794    merely zeroed.
5795 
5796    The user can set a value in the diagonal entry (or for the AIJ and
5797    row formats can optionally remove the main diagonal entry from the
5798    nonzero structure as well, by passing 0.0 as the final argument).
5799 
5800    For the parallel case, all processes that share the matrix (i.e.,
5801    those in the communicator used for matrix creation) MUST call this
5802    routine, regardless of whether any rows being zeroed are owned by
5803    them.
5804 
5805    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5806    list only rows local to itself).
5807 
5808    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5809    owns that are to be zeroed. This saves a global synchronization in the implementation.
5810 
5811    Level: intermediate
5812 
5813 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5814           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5815 @*/
5816 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5817 {
5818   PetscInt       numRows;
5819   const PetscInt *rows;
5820   PetscErrorCode ierr;
5821 
5822   PetscFunctionBegin;
5823   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5824   PetscValidType(mat,1);
5825   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5826   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5827   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5828   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5829   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5830   PetscFunctionReturn(0);
5831 }
5832 
5833 /*@
5834    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5835    of a set of rows of a matrix. These rows must be local to the process.
5836 
5837    Collective on Mat
5838 
5839    Input Parameters:
5840 +  mat - the matrix
5841 .  numRows - the number of rows to remove
5842 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5843 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5844 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5845 -  b - optional vector of right hand side, that will be adjusted by provided solution
5846 
5847    Notes:
5848    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5849    but does not release memory.  For the dense and block diagonal
5850    formats this does not alter the nonzero structure.
5851 
5852    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5853    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5854    merely zeroed.
5855 
5856    The user can set a value in the diagonal entry (or for the AIJ and
5857    row formats can optionally remove the main diagonal entry from the
5858    nonzero structure as well, by passing 0.0 as the final argument).
5859 
5860    For the parallel case, all processes that share the matrix (i.e.,
5861    those in the communicator used for matrix creation) MUST call this
5862    routine, regardless of whether any rows being zeroed are owned by
5863    them.
5864 
5865    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5866    list only rows local to itself).
5867 
5868    The grid coordinates are across the entire grid, not just the local portion
5869 
5870    In Fortran idxm and idxn should be declared as
5871 $     MatStencil idxm(4,m)
5872    and the values inserted using
5873 $    idxm(MatStencil_i,1) = i
5874 $    idxm(MatStencil_j,1) = j
5875 $    idxm(MatStencil_k,1) = k
5876 $    idxm(MatStencil_c,1) = c
5877    etc
5878 
5879    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5880    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5881    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5882    DM_BOUNDARY_PERIODIC boundary type.
5883 
5884    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
5885    a single value per point) you can skip filling those indices.
5886 
5887    Level: intermediate
5888 
5889 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5890           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5891 @*/
5892 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5893 {
5894   PetscInt       dim     = mat->stencil.dim;
5895   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5896   PetscInt       *dims   = mat->stencil.dims+1;
5897   PetscInt       *starts = mat->stencil.starts;
5898   PetscInt       *dxm    = (PetscInt*) rows;
5899   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5900   PetscErrorCode ierr;
5901 
5902   PetscFunctionBegin;
5903   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5904   PetscValidType(mat,1);
5905   if (numRows) PetscValidIntPointer(rows,3);
5906 
5907   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5908   for (i = 0; i < numRows; ++i) {
5909     /* Skip unused dimensions (they are ordered k, j, i, c) */
5910     for (j = 0; j < 3-sdim; ++j) dxm++;
5911     /* Local index in X dir */
5912     tmp = *dxm++ - starts[0];
5913     /* Loop over remaining dimensions */
5914     for (j = 0; j < dim-1; ++j) {
5915       /* If nonlocal, set index to be negative */
5916       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5917       /* Update local index */
5918       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5919     }
5920     /* Skip component slot if necessary */
5921     if (mat->stencil.noc) dxm++;
5922     /* Local row number */
5923     if (tmp >= 0) {
5924       jdxm[numNewRows++] = tmp;
5925     }
5926   }
5927   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5928   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5929   PetscFunctionReturn(0);
5930 }
5931 
5932 /*@
5933    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5934    of a set of rows and columns of a matrix.
5935 
5936    Collective on Mat
5937 
5938    Input Parameters:
5939 +  mat - the matrix
5940 .  numRows - the number of rows/columns to remove
5941 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5942 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5943 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5944 -  b - optional vector of right hand side, that will be adjusted by provided solution
5945 
5946    Notes:
5947    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5948    but does not release memory.  For the dense and block diagonal
5949    formats this does not alter the nonzero structure.
5950 
5951    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5952    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5953    merely zeroed.
5954 
5955    The user can set a value in the diagonal entry (or for the AIJ and
5956    row formats can optionally remove the main diagonal entry from the
5957    nonzero structure as well, by passing 0.0 as the final argument).
5958 
5959    For the parallel case, all processes that share the matrix (i.e.,
5960    those in the communicator used for matrix creation) MUST call this
5961    routine, regardless of whether any rows being zeroed are owned by
5962    them.
5963 
5964    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5965    list only rows local to itself, but the row/column numbers are given in local numbering).
5966 
5967    The grid coordinates are across the entire grid, not just the local portion
5968 
5969    In Fortran idxm and idxn should be declared as
5970 $     MatStencil idxm(4,m)
5971    and the values inserted using
5972 $    idxm(MatStencil_i,1) = i
5973 $    idxm(MatStencil_j,1) = j
5974 $    idxm(MatStencil_k,1) = k
5975 $    idxm(MatStencil_c,1) = c
5976    etc
5977 
5978    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5979    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5980    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5981    DM_BOUNDARY_PERIODIC boundary type.
5982 
5983    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
5984    a single value per point) you can skip filling those indices.
5985 
5986    Level: intermediate
5987 
5988 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5989           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5990 @*/
5991 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5992 {
5993   PetscInt       dim     = mat->stencil.dim;
5994   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5995   PetscInt       *dims   = mat->stencil.dims+1;
5996   PetscInt       *starts = mat->stencil.starts;
5997   PetscInt       *dxm    = (PetscInt*) rows;
5998   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5999   PetscErrorCode ierr;
6000 
6001   PetscFunctionBegin;
6002   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6003   PetscValidType(mat,1);
6004   if (numRows) PetscValidIntPointer(rows,3);
6005 
6006   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6007   for (i = 0; i < numRows; ++i) {
6008     /* Skip unused dimensions (they are ordered k, j, i, c) */
6009     for (j = 0; j < 3-sdim; ++j) dxm++;
6010     /* Local index in X dir */
6011     tmp = *dxm++ - starts[0];
6012     /* Loop over remaining dimensions */
6013     for (j = 0; j < dim-1; ++j) {
6014       /* If nonlocal, set index to be negative */
6015       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6016       /* Update local index */
6017       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6018     }
6019     /* Skip component slot if necessary */
6020     if (mat->stencil.noc) dxm++;
6021     /* Local row number */
6022     if (tmp >= 0) {
6023       jdxm[numNewRows++] = tmp;
6024     }
6025   }
6026   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6027   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6028   PetscFunctionReturn(0);
6029 }
6030 
6031 /*@C
6032    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6033    of a set of rows of a matrix; using local numbering of rows.
6034 
6035    Collective on Mat
6036 
6037    Input Parameters:
6038 +  mat - the matrix
6039 .  numRows - the number of rows to remove
6040 .  rows - the global row indices
6041 .  diag - value put in all diagonals of eliminated rows
6042 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6043 -  b - optional vector of right hand side, that will be adjusted by provided solution
6044 
6045    Notes:
6046    Before calling MatZeroRowsLocal(), the user must first set the
6047    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6048 
6049    For the AIJ matrix formats this removes the old nonzero structure,
6050    but does not release memory.  For the dense and block diagonal
6051    formats this does not alter the nonzero structure.
6052 
6053    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6054    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6055    merely zeroed.
6056 
6057    The user can set a value in the diagonal entry (or for the AIJ and
6058    row formats can optionally remove the main diagonal entry from the
6059    nonzero structure as well, by passing 0.0 as the final argument).
6060 
6061    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6062    owns that are to be zeroed. This saves a global synchronization in the implementation.
6063 
6064    Level: intermediate
6065 
6066 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6067           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6068 @*/
6069 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6070 {
6071   PetscErrorCode ierr;
6072 
6073   PetscFunctionBegin;
6074   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6075   PetscValidType(mat,1);
6076   if (numRows) PetscValidIntPointer(rows,3);
6077   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6078   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6079   MatCheckPreallocated(mat,1);
6080 
6081   if (mat->ops->zerorowslocal) {
6082     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6083   } else {
6084     IS             is, newis;
6085     const PetscInt *newRows;
6086 
6087     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6088     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6089     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6090     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6091     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6092     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6093     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6094     ierr = ISDestroy(&is);CHKERRQ(ierr);
6095   }
6096   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6097   PetscFunctionReturn(0);
6098 }
6099 
6100 /*@
6101    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6102    of a set of rows of a matrix; using local numbering of rows.
6103 
6104    Collective on Mat
6105 
6106    Input Parameters:
6107 +  mat - the matrix
6108 .  is - index set of rows to remove
6109 .  diag - value put in all diagonals of eliminated rows
6110 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6111 -  b - optional vector of right hand side, that will be adjusted by provided solution
6112 
6113    Notes:
6114    Before calling MatZeroRowsLocalIS(), the user must first set the
6115    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6116 
6117    For the AIJ matrix formats this removes the old nonzero structure,
6118    but does not release memory.  For the dense and block diagonal
6119    formats this does not alter the nonzero structure.
6120 
6121    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6122    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6123    merely zeroed.
6124 
6125    The user can set a value in the diagonal entry (or for the AIJ and
6126    row formats can optionally remove the main diagonal entry from the
6127    nonzero structure as well, by passing 0.0 as the final argument).
6128 
6129    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6130    owns that are to be zeroed. This saves a global synchronization in the implementation.
6131 
6132    Level: intermediate
6133 
6134 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6135           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6136 @*/
6137 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6138 {
6139   PetscErrorCode ierr;
6140   PetscInt       numRows;
6141   const PetscInt *rows;
6142 
6143   PetscFunctionBegin;
6144   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6145   PetscValidType(mat,1);
6146   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6147   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6148   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6149   MatCheckPreallocated(mat,1);
6150 
6151   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6152   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6153   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6154   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6155   PetscFunctionReturn(0);
6156 }
6157 
6158 /*@
6159    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6160    of a set of rows and columns of a matrix; using local numbering of rows.
6161 
6162    Collective on Mat
6163 
6164    Input Parameters:
6165 +  mat - the matrix
6166 .  numRows - the number of rows to remove
6167 .  rows - the global row indices
6168 .  diag - value put in all diagonals of eliminated rows
6169 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6170 -  b - optional vector of right hand side, that will be adjusted by provided solution
6171 
6172    Notes:
6173    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6174    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6175 
6176    The user can set a value in the diagonal entry (or for the AIJ and
6177    row formats can optionally remove the main diagonal entry from the
6178    nonzero structure as well, by passing 0.0 as the final argument).
6179 
6180    Level: intermediate
6181 
6182 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6183           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6184 @*/
6185 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6186 {
6187   PetscErrorCode ierr;
6188   IS             is, newis;
6189   const PetscInt *newRows;
6190 
6191   PetscFunctionBegin;
6192   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6193   PetscValidType(mat,1);
6194   if (numRows) PetscValidIntPointer(rows,3);
6195   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6196   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6197   MatCheckPreallocated(mat,1);
6198 
6199   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6200   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6201   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6202   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6203   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6204   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6205   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6206   ierr = ISDestroy(&is);CHKERRQ(ierr);
6207   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6208   PetscFunctionReturn(0);
6209 }
6210 
6211 /*@
6212    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6213    of a set of rows and columns of a matrix; using local numbering of rows.
6214 
6215    Collective on Mat
6216 
6217    Input Parameters:
6218 +  mat - the matrix
6219 .  is - index set of rows to remove
6220 .  diag - value put in all diagonals of eliminated rows
6221 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6222 -  b - optional vector of right hand side, that will be adjusted by provided solution
6223 
6224    Notes:
6225    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6226    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6227 
6228    The user can set a value in the diagonal entry (or for the AIJ and
6229    row formats can optionally remove the main diagonal entry from the
6230    nonzero structure as well, by passing 0.0 as the final argument).
6231 
6232    Level: intermediate
6233 
6234 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6235           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6236 @*/
6237 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6238 {
6239   PetscErrorCode ierr;
6240   PetscInt       numRows;
6241   const PetscInt *rows;
6242 
6243   PetscFunctionBegin;
6244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6245   PetscValidType(mat,1);
6246   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6249   MatCheckPreallocated(mat,1);
6250 
6251   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6252   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6253   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6254   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6255   PetscFunctionReturn(0);
6256 }
6257 
6258 /*@C
6259    MatGetSize - Returns the numbers of rows and columns in a matrix.
6260 
6261    Not Collective
6262 
6263    Input Parameter:
6264 .  mat - the matrix
6265 
6266    Output Parameters:
6267 +  m - the number of global rows
6268 -  n - the number of global columns
6269 
6270    Note: both output parameters can be NULL on input.
6271 
6272    Level: beginner
6273 
6274 .seealso: MatGetLocalSize()
6275 @*/
6276 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6277 {
6278   PetscFunctionBegin;
6279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6280   if (m) *m = mat->rmap->N;
6281   if (n) *n = mat->cmap->N;
6282   PetscFunctionReturn(0);
6283 }
6284 
6285 /*@C
6286    MatGetLocalSize - Returns the number of rows and columns in a matrix
6287    stored locally.  This information may be implementation dependent, so
6288    use with care.
6289 
6290    Not Collective
6291 
6292    Input Parameters:
6293 .  mat - the matrix
6294 
6295    Output Parameters:
6296 +  m - the number of local rows
6297 -  n - the number of local columns
6298 
6299    Note: both output parameters can be NULL on input.
6300 
6301    Level: beginner
6302 
6303 .seealso: MatGetSize()
6304 @*/
6305 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6306 {
6307   PetscFunctionBegin;
6308   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6309   if (m) PetscValidIntPointer(m,2);
6310   if (n) PetscValidIntPointer(n,3);
6311   if (m) *m = mat->rmap->n;
6312   if (n) *n = mat->cmap->n;
6313   PetscFunctionReturn(0);
6314 }
6315 
6316 /*@C
6317    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6318    this processor. (The columns of the "diagonal block")
6319 
6320    Not Collective, unless matrix has not been allocated, then collective on Mat
6321 
6322    Input Parameters:
6323 .  mat - the matrix
6324 
6325    Output Parameters:
6326 +  m - the global index of the first local column
6327 -  n - one more than the global index of the last local column
6328 
6329    Notes:
6330     both output parameters can be NULL on input.
6331 
6332    Level: developer
6333 
6334 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6335 
6336 @*/
6337 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6338 {
6339   PetscFunctionBegin;
6340   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6341   PetscValidType(mat,1);
6342   if (m) PetscValidIntPointer(m,2);
6343   if (n) PetscValidIntPointer(n,3);
6344   MatCheckPreallocated(mat,1);
6345   if (m) *m = mat->cmap->rstart;
6346   if (n) *n = mat->cmap->rend;
6347   PetscFunctionReturn(0);
6348 }
6349 
6350 /*@C
6351    MatGetOwnershipRange - Returns the range of matrix rows owned by
6352    this processor, assuming that the matrix is laid out with the first
6353    n1 rows on the first processor, the next n2 rows on the second, etc.
6354    For certain parallel layouts this range may not be well defined.
6355 
6356    Not Collective
6357 
6358    Input Parameters:
6359 .  mat - the matrix
6360 
6361    Output Parameters:
6362 +  m - the global index of the first local row
6363 -  n - one more than the global index of the last local row
6364 
6365    Note: Both output parameters can be NULL on input.
6366 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6367 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6368 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6369 
6370    Level: beginner
6371 
6372 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6373 
6374 @*/
6375 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6376 {
6377   PetscFunctionBegin;
6378   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6379   PetscValidType(mat,1);
6380   if (m) PetscValidIntPointer(m,2);
6381   if (n) PetscValidIntPointer(n,3);
6382   MatCheckPreallocated(mat,1);
6383   if (m) *m = mat->rmap->rstart;
6384   if (n) *n = mat->rmap->rend;
6385   PetscFunctionReturn(0);
6386 }
6387 
6388 /*@C
6389    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6390    each process
6391 
6392    Not Collective, unless matrix has not been allocated, then collective on Mat
6393 
6394    Input Parameters:
6395 .  mat - the matrix
6396 
6397    Output Parameters:
6398 .  ranges - start of each processors portion plus one more than the total length at the end
6399 
6400    Level: beginner
6401 
6402 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6403 
6404 @*/
6405 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6406 {
6407   PetscErrorCode ierr;
6408 
6409   PetscFunctionBegin;
6410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6411   PetscValidType(mat,1);
6412   MatCheckPreallocated(mat,1);
6413   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6414   PetscFunctionReturn(0);
6415 }
6416 
6417 /*@C
6418    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6419    this processor. (The columns of the "diagonal blocks" for each process)
6420 
6421    Not Collective, unless matrix has not been allocated, then collective on Mat
6422 
6423    Input Parameters:
6424 .  mat - the matrix
6425 
6426    Output Parameters:
6427 .  ranges - start of each processors portion plus one more then the total length at the end
6428 
6429    Level: beginner
6430 
6431 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6432 
6433 @*/
6434 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6435 {
6436   PetscErrorCode ierr;
6437 
6438   PetscFunctionBegin;
6439   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6440   PetscValidType(mat,1);
6441   MatCheckPreallocated(mat,1);
6442   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6443   PetscFunctionReturn(0);
6444 }
6445 
6446 /*@C
6447    MatGetOwnershipIS - Get row and column ownership as index sets
6448 
6449    Not Collective
6450 
6451    Input Arguments:
6452 .  A - matrix of type Elemental
6453 
6454    Output Arguments:
6455 +  rows - rows in which this process owns elements
6456 -  cols - columns in which this process owns elements
6457 
6458    Level: intermediate
6459 
6460 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6461 @*/
6462 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6463 {
6464   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6465 
6466   PetscFunctionBegin;
6467   MatCheckPreallocated(A,1);
6468   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6469   if (f) {
6470     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6471   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6472     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6473     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6474   }
6475   PetscFunctionReturn(0);
6476 }
6477 
6478 /*@C
6479    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6480    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6481    to complete the factorization.
6482 
6483    Collective on Mat
6484 
6485    Input Parameters:
6486 +  mat - the matrix
6487 .  row - row permutation
6488 .  column - column permutation
6489 -  info - structure containing
6490 $      levels - number of levels of fill.
6491 $      expected fill - as ratio of original fill.
6492 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6493                 missing diagonal entries)
6494 
6495    Output Parameters:
6496 .  fact - new matrix that has been symbolically factored
6497 
6498    Notes:
6499     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6500 
6501    Most users should employ the simplified KSP interface for linear solvers
6502    instead of working directly with matrix algebra routines such as this.
6503    See, e.g., KSPCreate().
6504 
6505    Level: developer
6506 
6507 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6508           MatGetOrdering(), MatFactorInfo
6509 
6510     Note: this uses the definition of level of fill as in Y. Saad, 2003
6511 
6512     Developer Note: fortran interface is not autogenerated as the f90
6513     interface defintion cannot be generated correctly [due to MatFactorInfo]
6514 
6515    References:
6516      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6517 @*/
6518 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6519 {
6520   PetscErrorCode ierr;
6521 
6522   PetscFunctionBegin;
6523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6524   PetscValidType(mat,1);
6525   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6526   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6527   PetscValidPointer(info,4);
6528   PetscValidPointer(fact,5);
6529   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6530   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6531   if (!(fact)->ops->ilufactorsymbolic) {
6532     MatSolverType spackage;
6533     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6534     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6535   }
6536   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6537   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6538   MatCheckPreallocated(mat,2);
6539 
6540   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6541   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6542   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6543   PetscFunctionReturn(0);
6544 }
6545 
6546 /*@C
6547    MatICCFactorSymbolic - Performs symbolic incomplete
6548    Cholesky factorization for a symmetric matrix.  Use
6549    MatCholeskyFactorNumeric() to complete the factorization.
6550 
6551    Collective on Mat
6552 
6553    Input Parameters:
6554 +  mat - the matrix
6555 .  perm - row and column permutation
6556 -  info - structure containing
6557 $      levels - number of levels of fill.
6558 $      expected fill - as ratio of original fill.
6559 
6560    Output Parameter:
6561 .  fact - the factored matrix
6562 
6563    Notes:
6564    Most users should employ the KSP interface for linear solvers
6565    instead of working directly with matrix algebra routines such as this.
6566    See, e.g., KSPCreate().
6567 
6568    Level: developer
6569 
6570 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6571 
6572     Note: this uses the definition of level of fill as in Y. Saad, 2003
6573 
6574     Developer Note: fortran interface is not autogenerated as the f90
6575     interface defintion cannot be generated correctly [due to MatFactorInfo]
6576 
6577    References:
6578      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6579 @*/
6580 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6581 {
6582   PetscErrorCode ierr;
6583 
6584   PetscFunctionBegin;
6585   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6586   PetscValidType(mat,1);
6587   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6588   PetscValidPointer(info,3);
6589   PetscValidPointer(fact,4);
6590   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6591   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6592   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6593   if (!(fact)->ops->iccfactorsymbolic) {
6594     MatSolverType spackage;
6595     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6596     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6597   }
6598   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6599   MatCheckPreallocated(mat,2);
6600 
6601   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6602   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6603   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6604   PetscFunctionReturn(0);
6605 }
6606 
6607 /*@C
6608    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6609    points to an array of valid matrices, they may be reused to store the new
6610    submatrices.
6611 
6612    Collective on Mat
6613 
6614    Input Parameters:
6615 +  mat - the matrix
6616 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6617 .  irow, icol - index sets of rows and columns to extract
6618 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6619 
6620    Output Parameter:
6621 .  submat - the array of submatrices
6622 
6623    Notes:
6624    MatCreateSubMatrices() can extract ONLY sequential submatrices
6625    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6626    to extract a parallel submatrix.
6627 
6628    Some matrix types place restrictions on the row and column
6629    indices, such as that they be sorted or that they be equal to each other.
6630 
6631    The index sets may not have duplicate entries.
6632 
6633    When extracting submatrices from a parallel matrix, each processor can
6634    form a different submatrix by setting the rows and columns of its
6635    individual index sets according to the local submatrix desired.
6636 
6637    When finished using the submatrices, the user should destroy
6638    them with MatDestroySubMatrices().
6639 
6640    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6641    original matrix has not changed from that last call to MatCreateSubMatrices().
6642 
6643    This routine creates the matrices in submat; you should NOT create them before
6644    calling it. It also allocates the array of matrix pointers submat.
6645 
6646    For BAIJ matrices the index sets must respect the block structure, that is if they
6647    request one row/column in a block, they must request all rows/columns that are in
6648    that block. For example, if the block size is 2 you cannot request just row 0 and
6649    column 0.
6650 
6651    Fortran Note:
6652    The Fortran interface is slightly different from that given below; it
6653    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6654 
6655    Level: advanced
6656 
6657 
6658 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6659 @*/
6660 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6661 {
6662   PetscErrorCode ierr;
6663   PetscInt       i;
6664   PetscBool      eq;
6665 
6666   PetscFunctionBegin;
6667   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6668   PetscValidType(mat,1);
6669   if (n) {
6670     PetscValidPointer(irow,3);
6671     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6672     PetscValidPointer(icol,4);
6673     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6674   }
6675   PetscValidPointer(submat,6);
6676   if (n && scall == MAT_REUSE_MATRIX) {
6677     PetscValidPointer(*submat,6);
6678     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6679   }
6680   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6681   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6682   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6683   MatCheckPreallocated(mat,1);
6684 
6685   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6686   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6687   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6688   for (i=0; i<n; i++) {
6689     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6690     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6691       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6692       if (eq) {
6693         if (mat->symmetric) {
6694           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6695         } else if (mat->hermitian) {
6696           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6697         } else if (mat->structurally_symmetric) {
6698           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6699         }
6700       }
6701     }
6702   }
6703   PetscFunctionReturn(0);
6704 }
6705 
6706 /*@C
6707    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6708 
6709    Collective on Mat
6710 
6711    Input Parameters:
6712 +  mat - the matrix
6713 .  n   - the number of submatrixes to be extracted
6714 .  irow, icol - index sets of rows and columns to extract
6715 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6716 
6717    Output Parameter:
6718 .  submat - the array of submatrices
6719 
6720    Level: advanced
6721 
6722 
6723 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6724 @*/
6725 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6726 {
6727   PetscErrorCode ierr;
6728   PetscInt       i;
6729   PetscBool      eq;
6730 
6731   PetscFunctionBegin;
6732   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6733   PetscValidType(mat,1);
6734   if (n) {
6735     PetscValidPointer(irow,3);
6736     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6737     PetscValidPointer(icol,4);
6738     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6739   }
6740   PetscValidPointer(submat,6);
6741   if (n && scall == MAT_REUSE_MATRIX) {
6742     PetscValidPointer(*submat,6);
6743     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6744   }
6745   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6746   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6747   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6748   MatCheckPreallocated(mat,1);
6749 
6750   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6751   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6752   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6753   for (i=0; i<n; i++) {
6754     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6755       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6756       if (eq) {
6757         if (mat->symmetric) {
6758           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6759         } else if (mat->hermitian) {
6760           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6761         } else if (mat->structurally_symmetric) {
6762           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6763         }
6764       }
6765     }
6766   }
6767   PetscFunctionReturn(0);
6768 }
6769 
6770 /*@C
6771    MatDestroyMatrices - Destroys an array of matrices.
6772 
6773    Collective on Mat
6774 
6775    Input Parameters:
6776 +  n - the number of local matrices
6777 -  mat - the matrices (note that this is a pointer to the array of matrices)
6778 
6779    Level: advanced
6780 
6781     Notes:
6782     Frees not only the matrices, but also the array that contains the matrices
6783            In Fortran will not free the array.
6784 
6785 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6786 @*/
6787 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6788 {
6789   PetscErrorCode ierr;
6790   PetscInt       i;
6791 
6792   PetscFunctionBegin;
6793   if (!*mat) PetscFunctionReturn(0);
6794   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6795   PetscValidPointer(mat,2);
6796 
6797   for (i=0; i<n; i++) {
6798     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6799   }
6800 
6801   /* memory is allocated even if n = 0 */
6802   ierr = PetscFree(*mat);CHKERRQ(ierr);
6803   PetscFunctionReturn(0);
6804 }
6805 
6806 /*@C
6807    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6808 
6809    Collective on Mat
6810 
6811    Input Parameters:
6812 +  n - the number of local matrices
6813 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6814                        sequence of MatCreateSubMatrices())
6815 
6816    Level: advanced
6817 
6818     Notes:
6819     Frees not only the matrices, but also the array that contains the matrices
6820            In Fortran will not free the array.
6821 
6822 .seealso: MatCreateSubMatrices()
6823 @*/
6824 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6825 {
6826   PetscErrorCode ierr;
6827   Mat            mat0;
6828 
6829   PetscFunctionBegin;
6830   if (!*mat) PetscFunctionReturn(0);
6831   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6832   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6833   PetscValidPointer(mat,2);
6834 
6835   mat0 = (*mat)[0];
6836   if (mat0 && mat0->ops->destroysubmatrices) {
6837     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6838   } else {
6839     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6840   }
6841   PetscFunctionReturn(0);
6842 }
6843 
6844 /*@C
6845    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6846 
6847    Collective on Mat
6848 
6849    Input Parameters:
6850 .  mat - the matrix
6851 
6852    Output Parameter:
6853 .  matstruct - the sequential matrix with the nonzero structure of mat
6854 
6855   Level: intermediate
6856 
6857 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6858 @*/
6859 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6860 {
6861   PetscErrorCode ierr;
6862 
6863   PetscFunctionBegin;
6864   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6865   PetscValidPointer(matstruct,2);
6866 
6867   PetscValidType(mat,1);
6868   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6869   MatCheckPreallocated(mat,1);
6870 
6871   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6872   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6873   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6874   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6875   PetscFunctionReturn(0);
6876 }
6877 
6878 /*@C
6879    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6880 
6881    Collective on Mat
6882 
6883    Input Parameters:
6884 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6885                        sequence of MatGetSequentialNonzeroStructure())
6886 
6887    Level: advanced
6888 
6889     Notes:
6890     Frees not only the matrices, but also the array that contains the matrices
6891 
6892 .seealso: MatGetSeqNonzeroStructure()
6893 @*/
6894 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6895 {
6896   PetscErrorCode ierr;
6897 
6898   PetscFunctionBegin;
6899   PetscValidPointer(mat,1);
6900   ierr = MatDestroy(mat);CHKERRQ(ierr);
6901   PetscFunctionReturn(0);
6902 }
6903 
6904 /*@
6905    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6906    replaces the index sets by larger ones that represent submatrices with
6907    additional overlap.
6908 
6909    Collective on Mat
6910 
6911    Input Parameters:
6912 +  mat - the matrix
6913 .  n   - the number of index sets
6914 .  is  - the array of index sets (these index sets will changed during the call)
6915 -  ov  - the additional overlap requested
6916 
6917    Options Database:
6918 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6919 
6920    Level: developer
6921 
6922 
6923 .seealso: MatCreateSubMatrices()
6924 @*/
6925 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6926 {
6927   PetscErrorCode ierr;
6928 
6929   PetscFunctionBegin;
6930   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6931   PetscValidType(mat,1);
6932   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6933   if (n) {
6934     PetscValidPointer(is,3);
6935     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6936   }
6937   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6938   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6939   MatCheckPreallocated(mat,1);
6940 
6941   if (!ov) PetscFunctionReturn(0);
6942   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6943   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6944   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6945   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6946   PetscFunctionReturn(0);
6947 }
6948 
6949 
6950 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6951 
6952 /*@
6953    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6954    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6955    additional overlap.
6956 
6957    Collective on Mat
6958 
6959    Input Parameters:
6960 +  mat - the matrix
6961 .  n   - the number of index sets
6962 .  is  - the array of index sets (these index sets will changed during the call)
6963 -  ov  - the additional overlap requested
6964 
6965    Options Database:
6966 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6967 
6968    Level: developer
6969 
6970 
6971 .seealso: MatCreateSubMatrices()
6972 @*/
6973 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6974 {
6975   PetscInt       i;
6976   PetscErrorCode ierr;
6977 
6978   PetscFunctionBegin;
6979   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6980   PetscValidType(mat,1);
6981   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6982   if (n) {
6983     PetscValidPointer(is,3);
6984     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6985   }
6986   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6987   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6988   MatCheckPreallocated(mat,1);
6989   if (!ov) PetscFunctionReturn(0);
6990   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6991   for(i=0; i<n; i++){
6992 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
6993   }
6994   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6995   PetscFunctionReturn(0);
6996 }
6997 
6998 
6999 
7000 
7001 /*@
7002    MatGetBlockSize - Returns the matrix block size.
7003 
7004    Not Collective
7005 
7006    Input Parameter:
7007 .  mat - the matrix
7008 
7009    Output Parameter:
7010 .  bs - block size
7011 
7012    Notes:
7013     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7014 
7015    If the block size has not been set yet this routine returns 1.
7016 
7017    Level: intermediate
7018 
7019 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7020 @*/
7021 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7022 {
7023   PetscFunctionBegin;
7024   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7025   PetscValidIntPointer(bs,2);
7026   *bs = PetscAbs(mat->rmap->bs);
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 /*@
7031    MatGetBlockSizes - Returns the matrix block row and column sizes.
7032 
7033    Not Collective
7034 
7035    Input Parameter:
7036 .  mat - the matrix
7037 
7038    Output Parameter:
7039 +  rbs - row block size
7040 -  cbs - column block size
7041 
7042    Notes:
7043     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7044     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7045 
7046    If a block size has not been set yet this routine returns 1.
7047 
7048    Level: intermediate
7049 
7050 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7051 @*/
7052 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7053 {
7054   PetscFunctionBegin;
7055   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7056   if (rbs) PetscValidIntPointer(rbs,2);
7057   if (cbs) PetscValidIntPointer(cbs,3);
7058   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7059   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7060   PetscFunctionReturn(0);
7061 }
7062 
7063 /*@
7064    MatSetBlockSize - Sets the matrix block size.
7065 
7066    Logically Collective on Mat
7067 
7068    Input Parameters:
7069 +  mat - the matrix
7070 -  bs - block size
7071 
7072    Notes:
7073     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7074     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7075 
7076     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7077     is compatible with the matrix local sizes.
7078 
7079    Level: intermediate
7080 
7081 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7082 @*/
7083 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7084 {
7085   PetscErrorCode ierr;
7086 
7087   PetscFunctionBegin;
7088   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7089   PetscValidLogicalCollectiveInt(mat,bs,2);
7090   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7091   PetscFunctionReturn(0);
7092 }
7093 
7094 /*@
7095    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7096 
7097    Logically Collective on Mat
7098 
7099    Input Parameters:
7100 +  mat - the matrix
7101 .  nblocks - the number of blocks on this process
7102 -  bsizes - the block sizes
7103 
7104    Notes:
7105     Currently used by PCVPBJACOBI for SeqAIJ matrices
7106 
7107    Level: intermediate
7108 
7109 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7110 @*/
7111 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7112 {
7113   PetscErrorCode ierr;
7114   PetscInt       i,ncnt = 0, nlocal;
7115 
7116   PetscFunctionBegin;
7117   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7118   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7119   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7120   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7121   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);
7122   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7123   mat->nblocks = nblocks;
7124   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7125   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7126   PetscFunctionReturn(0);
7127 }
7128 
7129 /*@C
7130    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7131 
7132    Logically Collective on Mat
7133 
7134    Input Parameters:
7135 .  mat - the matrix
7136 
7137    Output Parameters:
7138 +  nblocks - the number of blocks on this process
7139 -  bsizes - the block sizes
7140 
7141    Notes: Currently not supported from Fortran
7142 
7143    Level: intermediate
7144 
7145 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7146 @*/
7147 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7148 {
7149   PetscFunctionBegin;
7150   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7151   *nblocks = mat->nblocks;
7152   *bsizes  = mat->bsizes;
7153   PetscFunctionReturn(0);
7154 }
7155 
7156 /*@
7157    MatSetBlockSizes - Sets the matrix block row and column sizes.
7158 
7159    Logically Collective on Mat
7160 
7161    Input Parameters:
7162 +  mat - the matrix
7163 .  rbs - row block size
7164 -  cbs - column block size
7165 
7166    Notes:
7167     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7168     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7169     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7170 
7171     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7172     are compatible with the matrix local sizes.
7173 
7174     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7175 
7176    Level: intermediate
7177 
7178 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7179 @*/
7180 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7181 {
7182   PetscErrorCode ierr;
7183 
7184   PetscFunctionBegin;
7185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7186   PetscValidLogicalCollectiveInt(mat,rbs,2);
7187   PetscValidLogicalCollectiveInt(mat,cbs,3);
7188   if (mat->ops->setblocksizes) {
7189     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7190   }
7191   if (mat->rmap->refcnt) {
7192     ISLocalToGlobalMapping l2g = NULL;
7193     PetscLayout            nmap = NULL;
7194 
7195     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7196     if (mat->rmap->mapping) {
7197       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7198     }
7199     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7200     mat->rmap = nmap;
7201     mat->rmap->mapping = l2g;
7202   }
7203   if (mat->cmap->refcnt) {
7204     ISLocalToGlobalMapping l2g = NULL;
7205     PetscLayout            nmap = NULL;
7206 
7207     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7208     if (mat->cmap->mapping) {
7209       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7210     }
7211     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7212     mat->cmap = nmap;
7213     mat->cmap->mapping = l2g;
7214   }
7215   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7216   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7217   PetscFunctionReturn(0);
7218 }
7219 
7220 /*@
7221    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7222 
7223    Logically Collective on Mat
7224 
7225    Input Parameters:
7226 +  mat - the matrix
7227 .  fromRow - matrix from which to copy row block size
7228 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7229 
7230    Level: developer
7231 
7232 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7233 @*/
7234 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7235 {
7236   PetscErrorCode ierr;
7237 
7238   PetscFunctionBegin;
7239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7240   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7241   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7242   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7243   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7244   PetscFunctionReturn(0);
7245 }
7246 
7247 /*@
7248    MatResidual - Default routine to calculate the residual.
7249 
7250    Collective on Mat
7251 
7252    Input Parameters:
7253 +  mat - the matrix
7254 .  b   - the right-hand-side
7255 -  x   - the approximate solution
7256 
7257    Output Parameter:
7258 .  r - location to store the residual
7259 
7260    Level: developer
7261 
7262 .seealso: PCMGSetResidual()
7263 @*/
7264 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7265 {
7266   PetscErrorCode ierr;
7267 
7268   PetscFunctionBegin;
7269   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7270   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7271   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7272   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7273   PetscValidType(mat,1);
7274   MatCheckPreallocated(mat,1);
7275   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7276   if (!mat->ops->residual) {
7277     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7278     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7279   } else {
7280     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7281   }
7282   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7283   PetscFunctionReturn(0);
7284 }
7285 
7286 /*@C
7287     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7288 
7289    Collective on Mat
7290 
7291     Input Parameters:
7292 +   mat - the matrix
7293 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7294 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7295 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7296                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7297                  always used.
7298 
7299     Output Parameters:
7300 +   n - number of rows in the (possibly compressed) matrix
7301 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7302 .   ja - the column indices
7303 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7304            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7305 
7306     Level: developer
7307 
7308     Notes:
7309     You CANNOT change any of the ia[] or ja[] values.
7310 
7311     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7312 
7313     Fortran Notes:
7314     In Fortran use
7315 $
7316 $      PetscInt ia(1), ja(1)
7317 $      PetscOffset iia, jja
7318 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7319 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7320 
7321      or
7322 $
7323 $    PetscInt, pointer :: ia(:),ja(:)
7324 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7325 $    ! Access the ith and jth entries via ia(i) and ja(j)
7326 
7327 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7328 @*/
7329 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7330 {
7331   PetscErrorCode ierr;
7332 
7333   PetscFunctionBegin;
7334   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7335   PetscValidType(mat,1);
7336   PetscValidIntPointer(n,5);
7337   if (ia) PetscValidIntPointer(ia,6);
7338   if (ja) PetscValidIntPointer(ja,7);
7339   PetscValidIntPointer(done,8);
7340   MatCheckPreallocated(mat,1);
7341   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7342   else {
7343     *done = PETSC_TRUE;
7344     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7345     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7346     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7347   }
7348   PetscFunctionReturn(0);
7349 }
7350 
7351 /*@C
7352     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7353 
7354     Collective on Mat
7355 
7356     Input Parameters:
7357 +   mat - the matrix
7358 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7359 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7360                 symmetrized
7361 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7362                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7363                  always used.
7364 .   n - number of columns in the (possibly compressed) matrix
7365 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7366 -   ja - the row indices
7367 
7368     Output Parameters:
7369 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7370 
7371     Level: developer
7372 
7373 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7374 @*/
7375 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7376 {
7377   PetscErrorCode ierr;
7378 
7379   PetscFunctionBegin;
7380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7381   PetscValidType(mat,1);
7382   PetscValidIntPointer(n,4);
7383   if (ia) PetscValidIntPointer(ia,5);
7384   if (ja) PetscValidIntPointer(ja,6);
7385   PetscValidIntPointer(done,7);
7386   MatCheckPreallocated(mat,1);
7387   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7388   else {
7389     *done = PETSC_TRUE;
7390     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7391   }
7392   PetscFunctionReturn(0);
7393 }
7394 
7395 /*@C
7396     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7397     MatGetRowIJ().
7398 
7399     Collective on Mat
7400 
7401     Input Parameters:
7402 +   mat - the matrix
7403 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7404 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7405                 symmetrized
7406 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7407                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7408                  always used.
7409 .   n - size of (possibly compressed) matrix
7410 .   ia - the row pointers
7411 -   ja - the column indices
7412 
7413     Output Parameters:
7414 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7415 
7416     Note:
7417     This routine zeros out n, ia, and ja. This is to prevent accidental
7418     us of the array after it has been restored. If you pass NULL, it will
7419     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7420 
7421     Level: developer
7422 
7423 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7424 @*/
7425 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7426 {
7427   PetscErrorCode ierr;
7428 
7429   PetscFunctionBegin;
7430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7431   PetscValidType(mat,1);
7432   if (ia) PetscValidIntPointer(ia,6);
7433   if (ja) PetscValidIntPointer(ja,7);
7434   PetscValidIntPointer(done,8);
7435   MatCheckPreallocated(mat,1);
7436 
7437   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7438   else {
7439     *done = PETSC_TRUE;
7440     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7441     if (n)  *n = 0;
7442     if (ia) *ia = NULL;
7443     if (ja) *ja = NULL;
7444   }
7445   PetscFunctionReturn(0);
7446 }
7447 
7448 /*@C
7449     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7450     MatGetColumnIJ().
7451 
7452     Collective on Mat
7453 
7454     Input Parameters:
7455 +   mat - the matrix
7456 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7457 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7458                 symmetrized
7459 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7460                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7461                  always used.
7462 
7463     Output Parameters:
7464 +   n - size of (possibly compressed) matrix
7465 .   ia - the column pointers
7466 .   ja - the row indices
7467 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7468 
7469     Level: developer
7470 
7471 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7472 @*/
7473 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7474 {
7475   PetscErrorCode ierr;
7476 
7477   PetscFunctionBegin;
7478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7479   PetscValidType(mat,1);
7480   if (ia) PetscValidIntPointer(ia,5);
7481   if (ja) PetscValidIntPointer(ja,6);
7482   PetscValidIntPointer(done,7);
7483   MatCheckPreallocated(mat,1);
7484 
7485   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7486   else {
7487     *done = PETSC_TRUE;
7488     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7489     if (n)  *n = 0;
7490     if (ia) *ia = NULL;
7491     if (ja) *ja = NULL;
7492   }
7493   PetscFunctionReturn(0);
7494 }
7495 
7496 /*@C
7497     MatColoringPatch -Used inside matrix coloring routines that
7498     use MatGetRowIJ() and/or MatGetColumnIJ().
7499 
7500     Collective on Mat
7501 
7502     Input Parameters:
7503 +   mat - the matrix
7504 .   ncolors - max color value
7505 .   n   - number of entries in colorarray
7506 -   colorarray - array indicating color for each column
7507 
7508     Output Parameters:
7509 .   iscoloring - coloring generated using colorarray information
7510 
7511     Level: developer
7512 
7513 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7514 
7515 @*/
7516 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7517 {
7518   PetscErrorCode ierr;
7519 
7520   PetscFunctionBegin;
7521   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7522   PetscValidType(mat,1);
7523   PetscValidIntPointer(colorarray,4);
7524   PetscValidPointer(iscoloring,5);
7525   MatCheckPreallocated(mat,1);
7526 
7527   if (!mat->ops->coloringpatch) {
7528     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7529   } else {
7530     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7531   }
7532   PetscFunctionReturn(0);
7533 }
7534 
7535 
7536 /*@
7537    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7538 
7539    Logically Collective on Mat
7540 
7541    Input Parameter:
7542 .  mat - the factored matrix to be reset
7543 
7544    Notes:
7545    This routine should be used only with factored matrices formed by in-place
7546    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7547    format).  This option can save memory, for example, when solving nonlinear
7548    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7549    ILU(0) preconditioner.
7550 
7551    Note that one can specify in-place ILU(0) factorization by calling
7552 .vb
7553      PCType(pc,PCILU);
7554      PCFactorSeUseInPlace(pc);
7555 .ve
7556    or by using the options -pc_type ilu -pc_factor_in_place
7557 
7558    In-place factorization ILU(0) can also be used as a local
7559    solver for the blocks within the block Jacobi or additive Schwarz
7560    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7561    for details on setting local solver options.
7562 
7563    Most users should employ the simplified KSP interface for linear solvers
7564    instead of working directly with matrix algebra routines such as this.
7565    See, e.g., KSPCreate().
7566 
7567    Level: developer
7568 
7569 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7570 
7571 @*/
7572 PetscErrorCode MatSetUnfactored(Mat mat)
7573 {
7574   PetscErrorCode ierr;
7575 
7576   PetscFunctionBegin;
7577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7578   PetscValidType(mat,1);
7579   MatCheckPreallocated(mat,1);
7580   mat->factortype = MAT_FACTOR_NONE;
7581   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7582   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7583   PetscFunctionReturn(0);
7584 }
7585 
7586 /*MC
7587     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7588 
7589     Synopsis:
7590     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7591 
7592     Not collective
7593 
7594     Input Parameter:
7595 .   x - matrix
7596 
7597     Output Parameters:
7598 +   xx_v - the Fortran90 pointer to the array
7599 -   ierr - error code
7600 
7601     Example of Usage:
7602 .vb
7603       PetscScalar, pointer xx_v(:,:)
7604       ....
7605       call MatDenseGetArrayF90(x,xx_v,ierr)
7606       a = xx_v(3)
7607       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7608 .ve
7609 
7610     Level: advanced
7611 
7612 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7613 
7614 M*/
7615 
7616 /*MC
7617     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7618     accessed with MatDenseGetArrayF90().
7619 
7620     Synopsis:
7621     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7622 
7623     Not collective
7624 
7625     Input Parameters:
7626 +   x - matrix
7627 -   xx_v - the Fortran90 pointer to the array
7628 
7629     Output Parameter:
7630 .   ierr - error code
7631 
7632     Example of Usage:
7633 .vb
7634        PetscScalar, pointer xx_v(:,:)
7635        ....
7636        call MatDenseGetArrayF90(x,xx_v,ierr)
7637        a = xx_v(3)
7638        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7639 .ve
7640 
7641     Level: advanced
7642 
7643 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7644 
7645 M*/
7646 
7647 
7648 /*MC
7649     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7650 
7651     Synopsis:
7652     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7653 
7654     Not collective
7655 
7656     Input Parameter:
7657 .   x - matrix
7658 
7659     Output Parameters:
7660 +   xx_v - the Fortran90 pointer to the array
7661 -   ierr - error code
7662 
7663     Example of Usage:
7664 .vb
7665       PetscScalar, pointer xx_v(:)
7666       ....
7667       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7668       a = xx_v(3)
7669       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7670 .ve
7671 
7672     Level: advanced
7673 
7674 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7675 
7676 M*/
7677 
7678 /*MC
7679     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7680     accessed with MatSeqAIJGetArrayF90().
7681 
7682     Synopsis:
7683     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7684 
7685     Not collective
7686 
7687     Input Parameters:
7688 +   x - matrix
7689 -   xx_v - the Fortran90 pointer to the array
7690 
7691     Output Parameter:
7692 .   ierr - error code
7693 
7694     Example of Usage:
7695 .vb
7696        PetscScalar, pointer xx_v(:)
7697        ....
7698        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7699        a = xx_v(3)
7700        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7701 .ve
7702 
7703     Level: advanced
7704 
7705 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7706 
7707 M*/
7708 
7709 
7710 /*@
7711     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7712                       as the original matrix.
7713 
7714     Collective on Mat
7715 
7716     Input Parameters:
7717 +   mat - the original matrix
7718 .   isrow - parallel IS containing the rows this processor should obtain
7719 .   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.
7720 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7721 
7722     Output Parameter:
7723 .   newmat - the new submatrix, of the same type as the old
7724 
7725     Level: advanced
7726 
7727     Notes:
7728     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7729 
7730     Some matrix types place restrictions on the row and column indices, such
7731     as that they be sorted or that they be equal to each other.
7732 
7733     The index sets may not have duplicate entries.
7734 
7735       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7736    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7737    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7738    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7739    you are finished using it.
7740 
7741     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7742     the input matrix.
7743 
7744     If iscol is NULL then all columns are obtained (not supported in Fortran).
7745 
7746    Example usage:
7747    Consider the following 8x8 matrix with 34 non-zero values, that is
7748    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7749    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7750    as follows:
7751 
7752 .vb
7753             1  2  0  |  0  3  0  |  0  4
7754     Proc0   0  5  6  |  7  0  0  |  8  0
7755             9  0 10  | 11  0  0  | 12  0
7756     -------------------------------------
7757            13  0 14  | 15 16 17  |  0  0
7758     Proc1   0 18  0  | 19 20 21  |  0  0
7759             0  0  0  | 22 23  0  | 24  0
7760     -------------------------------------
7761     Proc2  25 26 27  |  0  0 28  | 29  0
7762            30  0  0  | 31 32 33  |  0 34
7763 .ve
7764 
7765     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7766 
7767 .vb
7768             2  0  |  0  3  0  |  0
7769     Proc0   5  6  |  7  0  0  |  8
7770     -------------------------------
7771     Proc1  18  0  | 19 20 21  |  0
7772     -------------------------------
7773     Proc2  26 27  |  0  0 28  | 29
7774             0  0  | 31 32 33  |  0
7775 .ve
7776 
7777 
7778 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
7779 @*/
7780 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7781 {
7782   PetscErrorCode ierr;
7783   PetscMPIInt    size;
7784   Mat            *local;
7785   IS             iscoltmp;
7786 
7787   PetscFunctionBegin;
7788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7789   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7790   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7791   PetscValidPointer(newmat,5);
7792   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7793   PetscValidType(mat,1);
7794   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7795   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7796 
7797   MatCheckPreallocated(mat,1);
7798   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7799 
7800   if (!iscol || isrow == iscol) {
7801     PetscBool   stride;
7802     PetscMPIInt grabentirematrix = 0,grab;
7803     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7804     if (stride) {
7805       PetscInt first,step,n,rstart,rend;
7806       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7807       if (step == 1) {
7808         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7809         if (rstart == first) {
7810           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7811           if (n == rend-rstart) {
7812             grabentirematrix = 1;
7813           }
7814         }
7815       }
7816     }
7817     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7818     if (grab) {
7819       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7820       if (cll == MAT_INITIAL_MATRIX) {
7821         *newmat = mat;
7822         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7823       }
7824       PetscFunctionReturn(0);
7825     }
7826   }
7827 
7828   if (!iscol) {
7829     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7830   } else {
7831     iscoltmp = iscol;
7832   }
7833 
7834   /* if original matrix is on just one processor then use submatrix generated */
7835   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7836     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7837     goto setproperties;
7838   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7839     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7840     *newmat = *local;
7841     ierr    = PetscFree(local);CHKERRQ(ierr);
7842     goto setproperties;
7843   } else if (!mat->ops->createsubmatrix) {
7844     /* Create a new matrix type that implements the operation using the full matrix */
7845     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7846     switch (cll) {
7847     case MAT_INITIAL_MATRIX:
7848       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7849       break;
7850     case MAT_REUSE_MATRIX:
7851       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7852       break;
7853     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7854     }
7855     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7856     goto setproperties;
7857   }
7858 
7859   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7860   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7861   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7862   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7863 
7864   /* Propagate symmetry information for diagonal blocks */
7865 setproperties:
7866   if (isrow == iscoltmp) {
7867     if (mat->symmetric_set && mat->symmetric) {
7868       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7869     }
7870     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
7871       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7872     }
7873     if (mat->hermitian_set && mat->hermitian) {
7874       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7875     }
7876     if (mat->spd_set && mat->spd) {
7877       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
7878     }
7879   }
7880 
7881   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7882   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7883   PetscFunctionReturn(0);
7884 }
7885 
7886 /*@
7887    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7888    used during the assembly process to store values that belong to
7889    other processors.
7890 
7891    Not Collective
7892 
7893    Input Parameters:
7894 +  mat   - the matrix
7895 .  size  - the initial size of the stash.
7896 -  bsize - the initial size of the block-stash(if used).
7897 
7898    Options Database Keys:
7899 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7900 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7901 
7902    Level: intermediate
7903 
7904    Notes:
7905      The block-stash is used for values set with MatSetValuesBlocked() while
7906      the stash is used for values set with MatSetValues()
7907 
7908      Run with the option -info and look for output of the form
7909      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7910      to determine the appropriate value, MM, to use for size and
7911      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7912      to determine the value, BMM to use for bsize
7913 
7914 
7915 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7916 
7917 @*/
7918 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7919 {
7920   PetscErrorCode ierr;
7921 
7922   PetscFunctionBegin;
7923   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7924   PetscValidType(mat,1);
7925   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7926   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7927   PetscFunctionReturn(0);
7928 }
7929 
7930 /*@
7931    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7932      the matrix
7933 
7934    Neighbor-wise Collective on Mat
7935 
7936    Input Parameters:
7937 +  mat   - the matrix
7938 .  x,y - the vectors
7939 -  w - where the result is stored
7940 
7941    Level: intermediate
7942 
7943    Notes:
7944     w may be the same vector as y.
7945 
7946     This allows one to use either the restriction or interpolation (its transpose)
7947     matrix to do the interpolation
7948 
7949 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7950 
7951 @*/
7952 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7953 {
7954   PetscErrorCode ierr;
7955   PetscInt       M,N,Ny;
7956 
7957   PetscFunctionBegin;
7958   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7959   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7960   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7961   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7962   PetscValidType(A,1);
7963   MatCheckPreallocated(A,1);
7964   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7965   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7966   if (M == Ny) {
7967     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7968   } else {
7969     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7970   }
7971   PetscFunctionReturn(0);
7972 }
7973 
7974 /*@
7975    MatInterpolate - y = A*x or A'*x depending on the shape of
7976      the matrix
7977 
7978    Neighbor-wise Collective on Mat
7979 
7980    Input Parameters:
7981 +  mat   - the matrix
7982 -  x,y - the vectors
7983 
7984    Level: intermediate
7985 
7986    Notes:
7987     This allows one to use either the restriction or interpolation (its transpose)
7988     matrix to do the interpolation
7989 
7990 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7991 
7992 @*/
7993 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7994 {
7995   PetscErrorCode ierr;
7996   PetscInt       M,N,Ny;
7997 
7998   PetscFunctionBegin;
7999   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8000   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8001   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8002   PetscValidType(A,1);
8003   MatCheckPreallocated(A,1);
8004   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8005   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8006   if (M == Ny) {
8007     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8008   } else {
8009     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8010   }
8011   PetscFunctionReturn(0);
8012 }
8013 
8014 /*@
8015    MatRestrict - y = A*x or A'*x
8016 
8017    Neighbor-wise Collective on Mat
8018 
8019    Input Parameters:
8020 +  mat   - the matrix
8021 -  x,y - the vectors
8022 
8023    Level: intermediate
8024 
8025    Notes:
8026     This allows one to use either the restriction or interpolation (its transpose)
8027     matrix to do the restriction
8028 
8029 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8030 
8031 @*/
8032 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8033 {
8034   PetscErrorCode ierr;
8035   PetscInt       M,N,Ny;
8036 
8037   PetscFunctionBegin;
8038   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8039   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8040   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8041   PetscValidType(A,1);
8042   MatCheckPreallocated(A,1);
8043 
8044   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8045   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8046   if (M == Ny) {
8047     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8048   } else {
8049     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8050   }
8051   PetscFunctionReturn(0);
8052 }
8053 
8054 /*@
8055    MatGetNullSpace - retrieves the null space of a matrix.
8056 
8057    Logically Collective on Mat
8058 
8059    Input Parameters:
8060 +  mat - the matrix
8061 -  nullsp - the null space object
8062 
8063    Level: developer
8064 
8065 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8066 @*/
8067 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8068 {
8069   PetscFunctionBegin;
8070   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8071   PetscValidPointer(nullsp,2);
8072   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8073   PetscFunctionReturn(0);
8074 }
8075 
8076 /*@
8077    MatSetNullSpace - attaches a null space to a matrix.
8078 
8079    Logically Collective on Mat
8080 
8081    Input Parameters:
8082 +  mat - the matrix
8083 -  nullsp - the null space object
8084 
8085    Level: advanced
8086 
8087    Notes:
8088       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8089 
8090       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8091       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8092 
8093       You can remove the null space by calling this routine with an nullsp of NULL
8094 
8095 
8096       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8097    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).
8098    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
8099    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
8100    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).
8101 
8102       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8103 
8104     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
8105     routine also automatically calls MatSetTransposeNullSpace().
8106 
8107 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8108 @*/
8109 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8110 {
8111   PetscErrorCode ierr;
8112 
8113   PetscFunctionBegin;
8114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8115   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8116   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8117   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8118   mat->nullsp = nullsp;
8119   if (mat->symmetric_set && mat->symmetric) {
8120     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8121   }
8122   PetscFunctionReturn(0);
8123 }
8124 
8125 /*@
8126    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8127 
8128    Logically Collective on Mat
8129 
8130    Input Parameters:
8131 +  mat - the matrix
8132 -  nullsp - the null space object
8133 
8134    Level: developer
8135 
8136 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8137 @*/
8138 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8139 {
8140   PetscFunctionBegin;
8141   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8142   PetscValidType(mat,1);
8143   PetscValidPointer(nullsp,2);
8144   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8145   PetscFunctionReturn(0);
8146 }
8147 
8148 /*@
8149    MatSetTransposeNullSpace - attaches a null space to a matrix.
8150 
8151    Logically Collective on Mat
8152 
8153    Input Parameters:
8154 +  mat - the matrix
8155 -  nullsp - the null space object
8156 
8157    Level: advanced
8158 
8159    Notes:
8160       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.
8161       You must also call MatSetNullSpace()
8162 
8163 
8164       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8165    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).
8166    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
8167    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
8168    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).
8169 
8170       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8171 
8172 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8173 @*/
8174 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8175 {
8176   PetscErrorCode ierr;
8177 
8178   PetscFunctionBegin;
8179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8180   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8181   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8182   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8183   mat->transnullsp = nullsp;
8184   PetscFunctionReturn(0);
8185 }
8186 
8187 /*@
8188    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8189         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8190 
8191    Logically Collective on Mat
8192 
8193    Input Parameters:
8194 +  mat - the matrix
8195 -  nullsp - the null space object
8196 
8197    Level: advanced
8198 
8199    Notes:
8200       Overwrites any previous near null space that may have been attached
8201 
8202       You can remove the null space by calling this routine with an nullsp of NULL
8203 
8204 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8205 @*/
8206 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8207 {
8208   PetscErrorCode ierr;
8209 
8210   PetscFunctionBegin;
8211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8212   PetscValidType(mat,1);
8213   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8214   MatCheckPreallocated(mat,1);
8215   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8216   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8217   mat->nearnullsp = nullsp;
8218   PetscFunctionReturn(0);
8219 }
8220 
8221 /*@
8222    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8223 
8224    Not Collective
8225 
8226    Input Parameters:
8227 .  mat - the matrix
8228 
8229    Output Parameters:
8230 .  nullsp - the null space object, NULL if not set
8231 
8232    Level: developer
8233 
8234 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8235 @*/
8236 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8237 {
8238   PetscFunctionBegin;
8239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8240   PetscValidType(mat,1);
8241   PetscValidPointer(nullsp,2);
8242   MatCheckPreallocated(mat,1);
8243   *nullsp = mat->nearnullsp;
8244   PetscFunctionReturn(0);
8245 }
8246 
8247 /*@C
8248    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8249 
8250    Collective on Mat
8251 
8252    Input Parameters:
8253 +  mat - the matrix
8254 .  row - row/column permutation
8255 .  fill - expected fill factor >= 1.0
8256 -  level - level of fill, for ICC(k)
8257 
8258    Notes:
8259    Probably really in-place only when level of fill is zero, otherwise allocates
8260    new space to store factored matrix and deletes previous memory.
8261 
8262    Most users should employ the simplified KSP interface for linear solvers
8263    instead of working directly with matrix algebra routines such as this.
8264    See, e.g., KSPCreate().
8265 
8266    Level: developer
8267 
8268 
8269 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8270 
8271     Developer Note: fortran interface is not autogenerated as the f90
8272     interface defintion cannot be generated correctly [due to MatFactorInfo]
8273 
8274 @*/
8275 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8276 {
8277   PetscErrorCode ierr;
8278 
8279   PetscFunctionBegin;
8280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8281   PetscValidType(mat,1);
8282   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8283   PetscValidPointer(info,3);
8284   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8285   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8286   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8287   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8288   MatCheckPreallocated(mat,1);
8289   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8290   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8291   PetscFunctionReturn(0);
8292 }
8293 
8294 /*@
8295    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8296          ghosted ones.
8297 
8298    Not Collective
8299 
8300    Input Parameters:
8301 +  mat - the matrix
8302 -  diag = the diagonal values, including ghost ones
8303 
8304    Level: developer
8305 
8306    Notes:
8307     Works only for MPIAIJ and MPIBAIJ matrices
8308 
8309 .seealso: MatDiagonalScale()
8310 @*/
8311 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8312 {
8313   PetscErrorCode ierr;
8314   PetscMPIInt    size;
8315 
8316   PetscFunctionBegin;
8317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8318   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8319   PetscValidType(mat,1);
8320 
8321   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8322   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8323   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8324   if (size == 1) {
8325     PetscInt n,m;
8326     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8327     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8328     if (m == n) {
8329       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8330     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8331   } else {
8332     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8333   }
8334   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8335   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8336   PetscFunctionReturn(0);
8337 }
8338 
8339 /*@
8340    MatGetInertia - Gets the inertia from a factored matrix
8341 
8342    Collective on Mat
8343 
8344    Input Parameter:
8345 .  mat - the matrix
8346 
8347    Output Parameters:
8348 +   nneg - number of negative eigenvalues
8349 .   nzero - number of zero eigenvalues
8350 -   npos - number of positive eigenvalues
8351 
8352    Level: advanced
8353 
8354    Notes:
8355     Matrix must have been factored by MatCholeskyFactor()
8356 
8357 
8358 @*/
8359 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8360 {
8361   PetscErrorCode ierr;
8362 
8363   PetscFunctionBegin;
8364   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8365   PetscValidType(mat,1);
8366   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8367   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8368   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8369   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8370   PetscFunctionReturn(0);
8371 }
8372 
8373 /* ----------------------------------------------------------------*/
8374 /*@C
8375    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8376 
8377    Neighbor-wise Collective on Mats
8378 
8379    Input Parameters:
8380 +  mat - the factored matrix
8381 -  b - the right-hand-side vectors
8382 
8383    Output Parameter:
8384 .  x - the result vectors
8385 
8386    Notes:
8387    The vectors b and x cannot be the same.  I.e., one cannot
8388    call MatSolves(A,x,x).
8389 
8390    Notes:
8391    Most users should employ the simplified KSP interface for linear solvers
8392    instead of working directly with matrix algebra routines such as this.
8393    See, e.g., KSPCreate().
8394 
8395    Level: developer
8396 
8397 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8398 @*/
8399 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8400 {
8401   PetscErrorCode ierr;
8402 
8403   PetscFunctionBegin;
8404   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8405   PetscValidType(mat,1);
8406   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8407   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8408   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8409 
8410   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8411   MatCheckPreallocated(mat,1);
8412   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8413   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8414   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8415   PetscFunctionReturn(0);
8416 }
8417 
8418 /*@
8419    MatIsSymmetric - Test whether a matrix is symmetric
8420 
8421    Collective on Mat
8422 
8423    Input Parameter:
8424 +  A - the matrix to test
8425 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8426 
8427    Output Parameters:
8428 .  flg - the result
8429 
8430    Notes:
8431     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8432 
8433    Level: intermediate
8434 
8435 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8436 @*/
8437 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8438 {
8439   PetscErrorCode ierr;
8440 
8441   PetscFunctionBegin;
8442   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8443   PetscValidBoolPointer(flg,2);
8444 
8445   if (!A->symmetric_set) {
8446     if (!A->ops->issymmetric) {
8447       MatType mattype;
8448       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8449       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8450     }
8451     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8452     if (!tol) {
8453       A->symmetric_set = PETSC_TRUE;
8454       A->symmetric     = *flg;
8455       if (A->symmetric) {
8456         A->structurally_symmetric_set = PETSC_TRUE;
8457         A->structurally_symmetric     = PETSC_TRUE;
8458       }
8459     }
8460   } else if (A->symmetric) {
8461     *flg = PETSC_TRUE;
8462   } else if (!tol) {
8463     *flg = PETSC_FALSE;
8464   } else {
8465     if (!A->ops->issymmetric) {
8466       MatType mattype;
8467       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8468       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8469     }
8470     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8471   }
8472   PetscFunctionReturn(0);
8473 }
8474 
8475 /*@
8476    MatIsHermitian - Test whether a matrix is Hermitian
8477 
8478    Collective on Mat
8479 
8480    Input Parameter:
8481 +  A - the matrix to test
8482 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8483 
8484    Output Parameters:
8485 .  flg - the result
8486 
8487    Level: intermediate
8488 
8489 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8490           MatIsSymmetricKnown(), MatIsSymmetric()
8491 @*/
8492 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8493 {
8494   PetscErrorCode ierr;
8495 
8496   PetscFunctionBegin;
8497   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8498   PetscValidBoolPointer(flg,2);
8499 
8500   if (!A->hermitian_set) {
8501     if (!A->ops->ishermitian) {
8502       MatType mattype;
8503       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8504       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8505     }
8506     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8507     if (!tol) {
8508       A->hermitian_set = PETSC_TRUE;
8509       A->hermitian     = *flg;
8510       if (A->hermitian) {
8511         A->structurally_symmetric_set = PETSC_TRUE;
8512         A->structurally_symmetric     = PETSC_TRUE;
8513       }
8514     }
8515   } else if (A->hermitian) {
8516     *flg = PETSC_TRUE;
8517   } else if (!tol) {
8518     *flg = PETSC_FALSE;
8519   } else {
8520     if (!A->ops->ishermitian) {
8521       MatType mattype;
8522       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8523       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8524     }
8525     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8526   }
8527   PetscFunctionReturn(0);
8528 }
8529 
8530 /*@
8531    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8532 
8533    Not Collective
8534 
8535    Input Parameter:
8536 .  A - the matrix to check
8537 
8538    Output Parameters:
8539 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8540 -  flg - the result
8541 
8542    Level: advanced
8543 
8544    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8545          if you want it explicitly checked
8546 
8547 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8548 @*/
8549 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8550 {
8551   PetscFunctionBegin;
8552   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8553   PetscValidPointer(set,2);
8554   PetscValidBoolPointer(flg,3);
8555   if (A->symmetric_set) {
8556     *set = PETSC_TRUE;
8557     *flg = A->symmetric;
8558   } else {
8559     *set = PETSC_FALSE;
8560   }
8561   PetscFunctionReturn(0);
8562 }
8563 
8564 /*@
8565    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8566 
8567    Not Collective
8568 
8569    Input Parameter:
8570 .  A - the matrix to check
8571 
8572    Output Parameters:
8573 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8574 -  flg - the result
8575 
8576    Level: advanced
8577 
8578    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8579          if you want it explicitly checked
8580 
8581 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8582 @*/
8583 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8584 {
8585   PetscFunctionBegin;
8586   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8587   PetscValidPointer(set,2);
8588   PetscValidBoolPointer(flg,3);
8589   if (A->hermitian_set) {
8590     *set = PETSC_TRUE;
8591     *flg = A->hermitian;
8592   } else {
8593     *set = PETSC_FALSE;
8594   }
8595   PetscFunctionReturn(0);
8596 }
8597 
8598 /*@
8599    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8600 
8601    Collective on Mat
8602 
8603    Input Parameter:
8604 .  A - the matrix to test
8605 
8606    Output Parameters:
8607 .  flg - the result
8608 
8609    Level: intermediate
8610 
8611 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8612 @*/
8613 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8614 {
8615   PetscErrorCode ierr;
8616 
8617   PetscFunctionBegin;
8618   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8619   PetscValidBoolPointer(flg,2);
8620   if (!A->structurally_symmetric_set) {
8621     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8622     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8623 
8624     A->structurally_symmetric_set = PETSC_TRUE;
8625   }
8626   *flg = A->structurally_symmetric;
8627   PetscFunctionReturn(0);
8628 }
8629 
8630 /*@
8631    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8632        to be communicated to other processors during the MatAssemblyBegin/End() process
8633 
8634     Not collective
8635 
8636    Input Parameter:
8637 .   vec - the vector
8638 
8639    Output Parameters:
8640 +   nstash   - the size of the stash
8641 .   reallocs - the number of additional mallocs incurred.
8642 .   bnstash   - the size of the block stash
8643 -   breallocs - the number of additional mallocs incurred.in the block stash
8644 
8645    Level: advanced
8646 
8647 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8648 
8649 @*/
8650 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8651 {
8652   PetscErrorCode ierr;
8653 
8654   PetscFunctionBegin;
8655   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8656   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8657   PetscFunctionReturn(0);
8658 }
8659 
8660 /*@C
8661    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8662      parallel layout
8663 
8664    Collective on Mat
8665 
8666    Input Parameter:
8667 .  mat - the matrix
8668 
8669    Output Parameter:
8670 +   right - (optional) vector that the matrix can be multiplied against
8671 -   left - (optional) vector that the matrix vector product can be stored in
8672 
8673    Notes:
8674     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().
8675 
8676   Notes:
8677     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8678 
8679   Level: advanced
8680 
8681 .seealso: MatCreate(), VecDestroy()
8682 @*/
8683 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8684 {
8685   PetscErrorCode ierr;
8686 
8687   PetscFunctionBegin;
8688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8689   PetscValidType(mat,1);
8690   if (mat->ops->getvecs) {
8691     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8692   } else {
8693     PetscInt rbs,cbs;
8694     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8695     if (right) {
8696       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8697       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8698       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8699       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8700       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8701       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8702     }
8703     if (left) {
8704       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8705       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8706       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8707       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8708       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8709       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8710     }
8711   }
8712   PetscFunctionReturn(0);
8713 }
8714 
8715 /*@C
8716    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8717      with default values.
8718 
8719    Not Collective
8720 
8721    Input Parameters:
8722 .    info - the MatFactorInfo data structure
8723 
8724 
8725    Notes:
8726     The solvers are generally used through the KSP and PC objects, for example
8727           PCLU, PCILU, PCCHOLESKY, PCICC
8728 
8729    Level: developer
8730 
8731 .seealso: MatFactorInfo
8732 
8733     Developer Note: fortran interface is not autogenerated as the f90
8734     interface defintion cannot be generated correctly [due to MatFactorInfo]
8735 
8736 @*/
8737 
8738 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8739 {
8740   PetscErrorCode ierr;
8741 
8742   PetscFunctionBegin;
8743   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8744   PetscFunctionReturn(0);
8745 }
8746 
8747 /*@
8748    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8749 
8750    Collective on Mat
8751 
8752    Input Parameters:
8753 +  mat - the factored matrix
8754 -  is - the index set defining the Schur indices (0-based)
8755 
8756    Notes:
8757     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8758 
8759    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8760 
8761    Level: developer
8762 
8763 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8764           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8765 
8766 @*/
8767 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8768 {
8769   PetscErrorCode ierr,(*f)(Mat,IS);
8770 
8771   PetscFunctionBegin;
8772   PetscValidType(mat,1);
8773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8774   PetscValidType(is,2);
8775   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8776   PetscCheckSameComm(mat,1,is,2);
8777   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8778   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8779   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");
8780   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8781   ierr = (*f)(mat,is);CHKERRQ(ierr);
8782   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8783   PetscFunctionReturn(0);
8784 }
8785 
8786 /*@
8787   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8788 
8789    Logically Collective on Mat
8790 
8791    Input Parameters:
8792 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8793 .  S - location where to return the Schur complement, can be NULL
8794 -  status - the status of the Schur complement matrix, can be NULL
8795 
8796    Notes:
8797    You must call MatFactorSetSchurIS() before calling this routine.
8798 
8799    The routine provides a copy of the Schur matrix stored within the solver data structures.
8800    The caller must destroy the object when it is no longer needed.
8801    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8802 
8803    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)
8804 
8805    Developer Notes:
8806     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8807    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8808 
8809    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8810 
8811    Level: advanced
8812 
8813    References:
8814 
8815 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8816 @*/
8817 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8818 {
8819   PetscErrorCode ierr;
8820 
8821   PetscFunctionBegin;
8822   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8823   if (S) PetscValidPointer(S,2);
8824   if (status) PetscValidPointer(status,3);
8825   if (S) {
8826     PetscErrorCode (*f)(Mat,Mat*);
8827 
8828     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8829     if (f) {
8830       ierr = (*f)(F,S);CHKERRQ(ierr);
8831     } else {
8832       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8833     }
8834   }
8835   if (status) *status = F->schur_status;
8836   PetscFunctionReturn(0);
8837 }
8838 
8839 /*@
8840   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8841 
8842    Logically Collective on Mat
8843 
8844    Input Parameters:
8845 +  F - the factored matrix obtained by calling MatGetFactor()
8846 .  *S - location where to return the Schur complement, can be NULL
8847 -  status - the status of the Schur complement matrix, can be NULL
8848 
8849    Notes:
8850    You must call MatFactorSetSchurIS() before calling this routine.
8851 
8852    Schur complement mode is currently implemented for sequential matrices.
8853    The routine returns a the Schur Complement stored within the data strutures of the solver.
8854    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8855    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8856 
8857    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8858 
8859    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8860 
8861    Level: advanced
8862 
8863    References:
8864 
8865 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8866 @*/
8867 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8868 {
8869   PetscFunctionBegin;
8870   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8871   if (S) PetscValidPointer(S,2);
8872   if (status) PetscValidPointer(status,3);
8873   if (S) *S = F->schur;
8874   if (status) *status = F->schur_status;
8875   PetscFunctionReturn(0);
8876 }
8877 
8878 /*@
8879   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8880 
8881    Logically Collective on Mat
8882 
8883    Input Parameters:
8884 +  F - the factored matrix obtained by calling MatGetFactor()
8885 .  *S - location where the Schur complement is stored
8886 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8887 
8888    Notes:
8889 
8890    Level: advanced
8891 
8892    References:
8893 
8894 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8895 @*/
8896 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8897 {
8898   PetscErrorCode ierr;
8899 
8900   PetscFunctionBegin;
8901   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8902   if (S) {
8903     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8904     *S = NULL;
8905   }
8906   F->schur_status = status;
8907   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8908   PetscFunctionReturn(0);
8909 }
8910 
8911 /*@
8912   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8913 
8914    Logically Collective on Mat
8915 
8916    Input Parameters:
8917 +  F - the factored matrix obtained by calling MatGetFactor()
8918 .  rhs - location where the right hand side of the Schur complement system is stored
8919 -  sol - location where the solution of the Schur complement system has to be returned
8920 
8921    Notes:
8922    The sizes of the vectors should match the size of the Schur complement
8923 
8924    Must be called after MatFactorSetSchurIS()
8925 
8926    Level: advanced
8927 
8928    References:
8929 
8930 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8931 @*/
8932 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8933 {
8934   PetscErrorCode ierr;
8935 
8936   PetscFunctionBegin;
8937   PetscValidType(F,1);
8938   PetscValidType(rhs,2);
8939   PetscValidType(sol,3);
8940   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8941   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8942   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8943   PetscCheckSameComm(F,1,rhs,2);
8944   PetscCheckSameComm(F,1,sol,3);
8945   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8946   switch (F->schur_status) {
8947   case MAT_FACTOR_SCHUR_FACTORED:
8948     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8949     break;
8950   case MAT_FACTOR_SCHUR_INVERTED:
8951     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8952     break;
8953   default:
8954     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8955     break;
8956   }
8957   PetscFunctionReturn(0);
8958 }
8959 
8960 /*@
8961   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8962 
8963    Logically Collective on Mat
8964 
8965    Input Parameters:
8966 +  F - the factored matrix obtained by calling MatGetFactor()
8967 .  rhs - location where the right hand side of the Schur complement system is stored
8968 -  sol - location where the solution of the Schur complement system has to be returned
8969 
8970    Notes:
8971    The sizes of the vectors should match the size of the Schur complement
8972 
8973    Must be called after MatFactorSetSchurIS()
8974 
8975    Level: advanced
8976 
8977    References:
8978 
8979 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
8980 @*/
8981 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8982 {
8983   PetscErrorCode ierr;
8984 
8985   PetscFunctionBegin;
8986   PetscValidType(F,1);
8987   PetscValidType(rhs,2);
8988   PetscValidType(sol,3);
8989   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8990   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8991   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8992   PetscCheckSameComm(F,1,rhs,2);
8993   PetscCheckSameComm(F,1,sol,3);
8994   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8995   switch (F->schur_status) {
8996   case MAT_FACTOR_SCHUR_FACTORED:
8997     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
8998     break;
8999   case MAT_FACTOR_SCHUR_INVERTED:
9000     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9001     break;
9002   default:
9003     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9004     break;
9005   }
9006   PetscFunctionReturn(0);
9007 }
9008 
9009 /*@
9010   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9011 
9012    Logically Collective on Mat
9013 
9014    Input Parameters:
9015 .  F - the factored matrix obtained by calling MatGetFactor()
9016 
9017    Notes:
9018     Must be called after MatFactorSetSchurIS().
9019 
9020    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9021 
9022    Level: advanced
9023 
9024    References:
9025 
9026 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9027 @*/
9028 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9029 {
9030   PetscErrorCode ierr;
9031 
9032   PetscFunctionBegin;
9033   PetscValidType(F,1);
9034   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9035   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9036   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9037   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9038   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9039   PetscFunctionReturn(0);
9040 }
9041 
9042 /*@
9043   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9044 
9045    Logically Collective on Mat
9046 
9047    Input Parameters:
9048 .  F - the factored matrix obtained by calling MatGetFactor()
9049 
9050    Notes:
9051     Must be called after MatFactorSetSchurIS().
9052 
9053    Level: advanced
9054 
9055    References:
9056 
9057 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9058 @*/
9059 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9060 {
9061   PetscErrorCode ierr;
9062 
9063   PetscFunctionBegin;
9064   PetscValidType(F,1);
9065   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9066   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9067   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9068   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9069   PetscFunctionReturn(0);
9070 }
9071 
9072 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9073 {
9074   Mat            AP;
9075   PetscErrorCode ierr;
9076 
9077   PetscFunctionBegin;
9078   ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr);
9079   ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr);
9080   ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr);
9081   ierr = MatDestroy(&AP);CHKERRQ(ierr);
9082   PetscFunctionReturn(0);
9083 }
9084 
9085 /*@
9086    MatPtAP - Creates the matrix product C = P^T * A * P
9087 
9088    Neighbor-wise Collective on Mat
9089 
9090    Input Parameters:
9091 +  A - the matrix
9092 .  P - the projection matrix
9093 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9094 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9095           if the result is a dense matrix this is irrelevent
9096 
9097    Output Parameters:
9098 .  C - the product matrix
9099 
9100    Notes:
9101    C will be created and must be destroyed by the user with MatDestroy().
9102 
9103    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9104 
9105    Level: intermediate
9106 
9107 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9108 @*/
9109 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9110 {
9111   PetscErrorCode ierr;
9112   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9113   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9114   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9115   PetscBool      sametype;
9116 
9117   PetscFunctionBegin;
9118   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9119   PetscValidType(A,1);
9120   MatCheckPreallocated(A,1);
9121   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9122   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9123   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9124   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9125   PetscValidType(P,2);
9126   MatCheckPreallocated(P,2);
9127   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9128   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9129 
9130   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);
9131   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);
9132   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9133   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9134 
9135   if (scall == MAT_REUSE_MATRIX) {
9136     PetscValidPointer(*C,5);
9137     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9138 
9139     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9140     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9141     if ((*C)->ops->ptapnumeric) {
9142       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9143     } else {
9144       ierr = MatPtAP_Basic(A,P,scall,fill,C);
9145     }
9146     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9147     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9148     PetscFunctionReturn(0);
9149   }
9150 
9151   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9152   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9153 
9154   fA = A->ops->ptap;
9155   fP = P->ops->ptap;
9156   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9157   if (fP == fA && sametype) {
9158     ptap = fA;
9159   } else {
9160     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9161     char ptapname[256];
9162     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9163     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9164     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9165     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9166     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9167     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9168   }
9169 
9170   if (!ptap) ptap = MatPtAP_Basic;
9171   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9172   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9173   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9174   if (A->symmetric_set && A->symmetric) {
9175     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9176   }
9177   PetscFunctionReturn(0);
9178 }
9179 
9180 /*@
9181    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9182 
9183    Neighbor-wise Collective on Mat
9184 
9185    Input Parameters:
9186 +  A - the matrix
9187 -  P - the projection matrix
9188 
9189    Output Parameters:
9190 .  C - the product matrix
9191 
9192    Notes:
9193    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9194    the user using MatDeatroy().
9195 
9196    This routine is currently only implemented for pairs of AIJ matrices and classes
9197    which inherit from AIJ.  C will be of type MATAIJ.
9198 
9199    Level: intermediate
9200 
9201 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9202 @*/
9203 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9204 {
9205   PetscErrorCode ierr;
9206 
9207   PetscFunctionBegin;
9208   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9209   PetscValidType(A,1);
9210   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9211   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9212   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9213   PetscValidType(P,2);
9214   MatCheckPreallocated(P,2);
9215   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9216   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9217   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9218   PetscValidType(C,3);
9219   MatCheckPreallocated(C,3);
9220   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9221   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);
9222   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);
9223   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);
9224   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);
9225   MatCheckPreallocated(A,1);
9226 
9227   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9228   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9229   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9230   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9231   PetscFunctionReturn(0);
9232 }
9233 
9234 /*@
9235    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9236 
9237    Neighbor-wise Collective on Mat
9238 
9239    Input Parameters:
9240 +  A - the matrix
9241 -  P - the projection matrix
9242 
9243    Output Parameters:
9244 .  C - the (i,j) structure of the product matrix
9245 
9246    Notes:
9247    C will be created and must be destroyed by the user with MatDestroy().
9248 
9249    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9250    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9251    this (i,j) structure by calling MatPtAPNumeric().
9252 
9253    Level: intermediate
9254 
9255 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9256 @*/
9257 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9258 {
9259   PetscErrorCode ierr;
9260 
9261   PetscFunctionBegin;
9262   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9263   PetscValidType(A,1);
9264   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9265   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9266   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9267   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9268   PetscValidType(P,2);
9269   MatCheckPreallocated(P,2);
9270   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9271   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9272   PetscValidPointer(C,3);
9273 
9274   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);
9275   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);
9276   MatCheckPreallocated(A,1);
9277 
9278   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9279   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9280   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9281   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9282 
9283   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9284   PetscFunctionReturn(0);
9285 }
9286 
9287 /*@
9288    MatRARt - Creates the matrix product C = R * A * R^T
9289 
9290    Neighbor-wise Collective on Mat
9291 
9292    Input Parameters:
9293 +  A - the matrix
9294 .  R - the projection matrix
9295 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9296 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9297           if the result is a dense matrix this is irrelevent
9298 
9299    Output Parameters:
9300 .  C - the product matrix
9301 
9302    Notes:
9303    C will be created and must be destroyed by the user with MatDestroy().
9304 
9305    This routine is currently only implemented for pairs of AIJ matrices and classes
9306    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9307    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9308    We recommend using MatPtAP().
9309 
9310    Level: intermediate
9311 
9312 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9313 @*/
9314 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9315 {
9316   PetscErrorCode ierr;
9317 
9318   PetscFunctionBegin;
9319   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9320   PetscValidType(A,1);
9321   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9322   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9323   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9324   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9325   PetscValidType(R,2);
9326   MatCheckPreallocated(R,2);
9327   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9328   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9329   PetscValidPointer(C,3);
9330   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);
9331 
9332   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9333   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9334   MatCheckPreallocated(A,1);
9335 
9336   if (!A->ops->rart) {
9337     Mat Rt;
9338     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9339     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9340     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9341     PetscFunctionReturn(0);
9342   }
9343   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9344   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9345   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9346   PetscFunctionReturn(0);
9347 }
9348 
9349 /*@
9350    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9351 
9352    Neighbor-wise Collective on Mat
9353 
9354    Input Parameters:
9355 +  A - the matrix
9356 -  R - the projection matrix
9357 
9358    Output Parameters:
9359 .  C - the product matrix
9360 
9361    Notes:
9362    C must have been created by calling MatRARtSymbolic and must be destroyed by
9363    the user using MatDestroy().
9364 
9365    This routine is currently only implemented for pairs of AIJ matrices and classes
9366    which inherit from AIJ.  C will be of type MATAIJ.
9367 
9368    Level: intermediate
9369 
9370 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9371 @*/
9372 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9373 {
9374   PetscErrorCode ierr;
9375 
9376   PetscFunctionBegin;
9377   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9378   PetscValidType(A,1);
9379   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9380   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9381   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9382   PetscValidType(R,2);
9383   MatCheckPreallocated(R,2);
9384   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9385   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9386   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9387   PetscValidType(C,3);
9388   MatCheckPreallocated(C,3);
9389   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9390   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);
9391   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);
9392   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);
9393   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);
9394   MatCheckPreallocated(A,1);
9395 
9396   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9397   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9398   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9399   PetscFunctionReturn(0);
9400 }
9401 
9402 /*@
9403    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9404 
9405    Neighbor-wise Collective on Mat
9406 
9407    Input Parameters:
9408 +  A - the matrix
9409 -  R - the projection matrix
9410 
9411    Output Parameters:
9412 .  C - the (i,j) structure of the product matrix
9413 
9414    Notes:
9415    C will be created and must be destroyed by the user with MatDestroy().
9416 
9417    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9418    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9419    this (i,j) structure by calling MatRARtNumeric().
9420 
9421    Level: intermediate
9422 
9423 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9424 @*/
9425 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9426 {
9427   PetscErrorCode ierr;
9428 
9429   PetscFunctionBegin;
9430   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9431   PetscValidType(A,1);
9432   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9433   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9434   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9435   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9436   PetscValidType(R,2);
9437   MatCheckPreallocated(R,2);
9438   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9439   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9440   PetscValidPointer(C,3);
9441 
9442   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);
9443   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);
9444   MatCheckPreallocated(A,1);
9445   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9446   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9447   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9448 
9449   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9450   PetscFunctionReturn(0);
9451 }
9452 
9453 /*@
9454    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9455 
9456    Neighbor-wise Collective on Mat
9457 
9458    Input Parameters:
9459 +  A - the left matrix
9460 .  B - the right matrix
9461 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9462 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9463           if the result is a dense matrix this is irrelevent
9464 
9465    Output Parameters:
9466 .  C - the product matrix
9467 
9468    Notes:
9469    Unless scall is MAT_REUSE_MATRIX C will be created.
9470 
9471    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
9472    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9473 
9474    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9475    actually needed.
9476 
9477    If you have many matrices with the same non-zero structure to multiply, you
9478    should either
9479 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9480 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9481    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
9482    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9483 
9484    Level: intermediate
9485 
9486 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9487 @*/
9488 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9489 {
9490   PetscErrorCode ierr;
9491   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9492   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9493   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9494   Mat            T;
9495   PetscBool      istrans;
9496 
9497   PetscFunctionBegin;
9498   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9499   PetscValidType(A,1);
9500   MatCheckPreallocated(A,1);
9501   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9502   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9503   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9504   PetscValidType(B,2);
9505   MatCheckPreallocated(B,2);
9506   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9507   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9508   PetscValidPointer(C,3);
9509   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9510   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);
9511   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9512   if (istrans) {
9513     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9514     ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9515     PetscFunctionReturn(0);
9516   } else {
9517     ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9518     if (istrans) {
9519       ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9520       ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr);
9521       PetscFunctionReturn(0);
9522     }
9523   }
9524   if (scall == MAT_REUSE_MATRIX) {
9525     PetscValidPointer(*C,5);
9526     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9527     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9528     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9529     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9530     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9531     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9532     PetscFunctionReturn(0);
9533   }
9534   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9535   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9536 
9537   fA = A->ops->matmult;
9538   fB = B->ops->matmult;
9539   if (fB == fA && fB) mult = fB;
9540   else {
9541     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9542     char multname[256];
9543     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9544     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9545     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9546     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9547     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9548     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9549     if (!mult) {
9550       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr);
9551     }
9552     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);
9553   }
9554   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9555   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9556   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9557   PetscFunctionReturn(0);
9558 }
9559 
9560 /*@
9561    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9562    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9563 
9564    Neighbor-wise Collective on Mat
9565 
9566    Input Parameters:
9567 +  A - the left matrix
9568 .  B - the right matrix
9569 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9570       if C is a dense matrix this is irrelevent
9571 
9572    Output Parameters:
9573 .  C - the product matrix
9574 
9575    Notes:
9576    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9577    actually needed.
9578 
9579    This routine is currently implemented for
9580     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9581     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9582     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9583 
9584    Level: intermediate
9585 
9586    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9587      We should incorporate them into PETSc.
9588 
9589 .seealso: MatMatMult(), MatMatMultNumeric()
9590 @*/
9591 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9592 {
9593   Mat            T = NULL;
9594   PetscBool      istrans;
9595   PetscErrorCode ierr;
9596   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9597   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9598   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9599 
9600   PetscFunctionBegin;
9601   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9602   PetscValidType(A,1);
9603   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9604   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9605 
9606   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9607   PetscValidType(B,2);
9608   MatCheckPreallocated(B,2);
9609   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9610   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9611   PetscValidPointer(C,3);
9612 
9613   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);
9614   if (fill == PETSC_DEFAULT) fill = 2.0;
9615   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9616   MatCheckPreallocated(A,1);
9617 
9618   Asymbolic = A->ops->matmultsymbolic;
9619   Bsymbolic = B->ops->matmultsymbolic;
9620   if (Asymbolic == Bsymbolic && Asymbolic) symbolic = Bsymbolic;
9621   else { /* dispatch based on the type of A and B */
9622     char symbolicname[256];
9623     ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9624     if (!istrans) {
9625       ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9626       ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9627       ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9628     } else {
9629       ierr = PetscStrncpy(symbolicname,"MatTransposeMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9630       ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9631       ierr = PetscStrlcat(symbolicname,((PetscObject)T)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9632       ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9633     }
9634     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9635     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9636     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9637     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);
9638   }
9639   ierr = PetscLogEventBegin(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9640   *C = NULL;
9641   ierr = (*symbolic)(!T ? A : T,B,fill,C);CHKERRQ(ierr);
9642   ierr = PetscLogEventEnd(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9643   PetscFunctionReturn(0);
9644 }
9645 
9646 /*@
9647    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9648    Call this routine after first calling MatMatMultSymbolic().
9649 
9650    Neighbor-wise Collective on Mat
9651 
9652    Input Parameters:
9653 +  A - the left matrix
9654 -  B - the right matrix
9655 
9656    Output Parameters:
9657 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9658 
9659    Notes:
9660    C must have been created with MatMatMultSymbolic().
9661 
9662    This routine is currently implemented for
9663     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9664     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9665     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9666 
9667    Level: intermediate
9668 
9669 .seealso: MatMatMult(), MatMatMultSymbolic()
9670 @*/
9671 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9672 {
9673   PetscErrorCode ierr;
9674 
9675   PetscFunctionBegin;
9676   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
9677   PetscFunctionReturn(0);
9678 }
9679 
9680 /*@
9681    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9682 
9683    Neighbor-wise Collective on Mat
9684 
9685    Input Parameters:
9686 +  A - the left matrix
9687 .  B - the right matrix
9688 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9689 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9690 
9691    Output Parameters:
9692 .  C - the product matrix
9693 
9694    Notes:
9695    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9696 
9697    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9698 
9699   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9700    actually needed.
9701 
9702    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9703    and for pairs of MPIDense matrices.
9704 
9705    Options Database Keys:
9706 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9707                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9708                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9709 
9710    Level: intermediate
9711 
9712 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9713 @*/
9714 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9715 {
9716   PetscErrorCode ierr;
9717   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9718   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9719   Mat            T;
9720   PetscBool      istrans;
9721 
9722   PetscFunctionBegin;
9723   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9724   PetscValidType(A,1);
9725   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9726   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9727   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9728   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9729   PetscValidType(B,2);
9730   MatCheckPreallocated(B,2);
9731   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9732   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9733   PetscValidPointer(C,3);
9734   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);
9735   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9736   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9737   MatCheckPreallocated(A,1);
9738 
9739   ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9740   if (istrans) {
9741     ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9742     ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr);
9743     PetscFunctionReturn(0);
9744   }
9745   fA = A->ops->mattransposemult;
9746   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9747   fB = B->ops->mattransposemult;
9748   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9749   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);
9750 
9751   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9752   if (scall == MAT_INITIAL_MATRIX) {
9753     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9754     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9755     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9756   }
9757   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9758   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9759   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9760   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9761   PetscFunctionReturn(0);
9762 }
9763 
9764 /*@
9765    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9766 
9767    Neighbor-wise Collective on Mat
9768 
9769    Input Parameters:
9770 +  A - the left matrix
9771 .  B - the right matrix
9772 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9773 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9774 
9775    Output Parameters:
9776 .  C - the product matrix
9777 
9778    Notes:
9779    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9780 
9781    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9782 
9783   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9784    actually needed.
9785 
9786    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9787    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9788 
9789    Level: intermediate
9790 
9791 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9792 @*/
9793 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9794 {
9795   PetscErrorCode ierr;
9796   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9797   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9798   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9799   Mat            T;
9800   PetscBool      flg;
9801 
9802   PetscFunctionBegin;
9803   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9804   PetscValidType(A,1);
9805   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9806   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9807   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9808   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9809   PetscValidType(B,2);
9810   MatCheckPreallocated(B,2);
9811   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9812   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9813   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);
9814   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9815   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9816   MatCheckPreallocated(A,1);
9817 
9818   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&flg);CHKERRQ(ierr);
9819   if (flg) {
9820     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9821     ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9822     PetscFunctionReturn(0);
9823   }
9824   if (scall == MAT_REUSE_MATRIX) {
9825     PetscValidPointer(*C,5);
9826     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9827     ierr = PetscObjectTypeCompareAny((PetscObject)*C,&flg,MATDENSE,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9828     if (flg) {
9829       ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9830       ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9831       ierr = (*(*C)->ops->transposematmultnumeric)(A,B,*C);CHKERRQ(ierr);
9832       ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9833       ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9834       PetscFunctionReturn(0);
9835     }
9836   }
9837 
9838   fA = A->ops->transposematmult;
9839   fB = B->ops->transposematmult;
9840   if (fB == fA && fA) transposematmult = fA;
9841   else {
9842     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9843     char multname[256];
9844     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9845     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9846     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9847     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9848     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9849     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9850     if (!transposematmult) {
9851       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr);
9852     }
9853     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);
9854   }
9855   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9856   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9857   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9858   PetscFunctionReturn(0);
9859 }
9860 
9861 /*@
9862    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9863 
9864    Neighbor-wise Collective on Mat
9865 
9866    Input Parameters:
9867 +  A - the left matrix
9868 .  B - the middle matrix
9869 .  C - the right matrix
9870 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9871 -  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
9872           if the result is a dense matrix this is irrelevent
9873 
9874    Output Parameters:
9875 .  D - the product matrix
9876 
9877    Notes:
9878    Unless scall is MAT_REUSE_MATRIX D will be created.
9879 
9880    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9881 
9882    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9883    actually needed.
9884 
9885    If you have many matrices with the same non-zero structure to multiply, you
9886    should use MAT_REUSE_MATRIX in all calls but the first or
9887 
9888    Level: intermediate
9889 
9890 .seealso: MatMatMult, MatPtAP()
9891 @*/
9892 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9893 {
9894   PetscErrorCode ierr;
9895   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9896   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9897   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9898   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9899 
9900   PetscFunctionBegin;
9901   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9902   PetscValidType(A,1);
9903   MatCheckPreallocated(A,1);
9904   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9905   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9906   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9907   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9908   PetscValidType(B,2);
9909   MatCheckPreallocated(B,2);
9910   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9911   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9912   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9913   PetscValidPointer(C,3);
9914   MatCheckPreallocated(C,3);
9915   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9916   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9917   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);
9918   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);
9919   if (scall == MAT_REUSE_MATRIX) {
9920     PetscValidPointer(*D,6);
9921     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9922     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9923     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9924     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9925     PetscFunctionReturn(0);
9926   }
9927   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9928   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9929 
9930   fA = A->ops->matmatmult;
9931   fB = B->ops->matmatmult;
9932   fC = C->ops->matmatmult;
9933   if (fA == fB && fA == fC) {
9934     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9935     mult = fA;
9936   } else {
9937     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9938     char multname[256];
9939     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9940     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9941     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9942     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9943     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9944     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9945     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9946     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9947     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);
9948   }
9949   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9950   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9951   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9952   PetscFunctionReturn(0);
9953 }
9954 
9955 /*@
9956    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9957 
9958    Collective on Mat
9959 
9960    Input Parameters:
9961 +  mat - the matrix
9962 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9963 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9964 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9965 
9966    Output Parameter:
9967 .  matredundant - redundant matrix
9968 
9969    Notes:
9970    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9971    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9972 
9973    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9974    calling it.
9975 
9976    Level: advanced
9977 
9978 
9979 .seealso: MatDestroy()
9980 @*/
9981 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9982 {
9983   PetscErrorCode ierr;
9984   MPI_Comm       comm;
9985   PetscMPIInt    size;
9986   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9987   Mat_Redundant  *redund=NULL;
9988   PetscSubcomm   psubcomm=NULL;
9989   MPI_Comm       subcomm_in=subcomm;
9990   Mat            *matseq;
9991   IS             isrow,iscol;
9992   PetscBool      newsubcomm=PETSC_FALSE;
9993 
9994   PetscFunctionBegin;
9995   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9996   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9997     PetscValidPointer(*matredundant,5);
9998     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9999   }
10000 
10001   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10002   if (size == 1 || nsubcomm == 1) {
10003     if (reuse == MAT_INITIAL_MATRIX) {
10004       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10005     } else {
10006       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");
10007       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10008     }
10009     PetscFunctionReturn(0);
10010   }
10011 
10012   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10013   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10014   MatCheckPreallocated(mat,1);
10015 
10016   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10017   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10018     /* create psubcomm, then get subcomm */
10019     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10020     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10021     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10022 
10023     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10024     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10025     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10026     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10027     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10028     newsubcomm = PETSC_TRUE;
10029     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10030   }
10031 
10032   /* get isrow, iscol and a local sequential matrix matseq[0] */
10033   if (reuse == MAT_INITIAL_MATRIX) {
10034     mloc_sub = PETSC_DECIDE;
10035     nloc_sub = PETSC_DECIDE;
10036     if (bs < 1) {
10037       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10038       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10039     } else {
10040       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10041       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10042     }
10043     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10044     rstart = rend - mloc_sub;
10045     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10046     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10047   } else { /* reuse == MAT_REUSE_MATRIX */
10048     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");
10049     /* retrieve subcomm */
10050     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10051     redund = (*matredundant)->redundant;
10052     isrow  = redund->isrow;
10053     iscol  = redund->iscol;
10054     matseq = redund->matseq;
10055   }
10056   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10057 
10058   /* get matredundant over subcomm */
10059   if (reuse == MAT_INITIAL_MATRIX) {
10060     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10061 
10062     /* create a supporting struct and attach it to C for reuse */
10063     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10064     (*matredundant)->redundant = redund;
10065     redund->isrow              = isrow;
10066     redund->iscol              = iscol;
10067     redund->matseq             = matseq;
10068     if (newsubcomm) {
10069       redund->subcomm          = subcomm;
10070     } else {
10071       redund->subcomm          = MPI_COMM_NULL;
10072     }
10073   } else {
10074     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10075   }
10076   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10077   PetscFunctionReturn(0);
10078 }
10079 
10080 /*@C
10081    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10082    a given 'mat' object. Each submatrix can span multiple procs.
10083 
10084    Collective on Mat
10085 
10086    Input Parameters:
10087 +  mat - the matrix
10088 .  subcomm - the subcommunicator obtained by com_split(comm)
10089 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10090 
10091    Output Parameter:
10092 .  subMat - 'parallel submatrices each spans a given subcomm
10093 
10094   Notes:
10095   The submatrix partition across processors is dictated by 'subComm' a
10096   communicator obtained by com_split(comm). The comm_split
10097   is not restriced to be grouped with consecutive original ranks.
10098 
10099   Due the comm_split() usage, the parallel layout of the submatrices
10100   map directly to the layout of the original matrix [wrt the local
10101   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10102   into the 'DiagonalMat' of the subMat, hence it is used directly from
10103   the subMat. However the offDiagMat looses some columns - and this is
10104   reconstructed with MatSetValues()
10105 
10106   Level: advanced
10107 
10108 
10109 .seealso: MatCreateSubMatrices()
10110 @*/
10111 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10112 {
10113   PetscErrorCode ierr;
10114   PetscMPIInt    commsize,subCommSize;
10115 
10116   PetscFunctionBegin;
10117   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10118   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10119   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10120 
10121   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");
10122   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10123   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10124   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10125   PetscFunctionReturn(0);
10126 }
10127 
10128 /*@
10129    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10130 
10131    Not Collective
10132 
10133    Input Arguments:
10134 +  mat - matrix to extract local submatrix from
10135 .  isrow - local row indices for submatrix
10136 -  iscol - local column indices for submatrix
10137 
10138    Output Arguments:
10139 .  submat - the submatrix
10140 
10141    Level: intermediate
10142 
10143    Notes:
10144    The submat should be returned with MatRestoreLocalSubMatrix().
10145 
10146    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10147    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10148 
10149    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10150    MatSetValuesBlockedLocal() will also be implemented.
10151 
10152    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10153    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10154 
10155 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10156 @*/
10157 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10158 {
10159   PetscErrorCode ierr;
10160 
10161   PetscFunctionBegin;
10162   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10163   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10164   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10165   PetscCheckSameComm(isrow,2,iscol,3);
10166   PetscValidPointer(submat,4);
10167   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10168 
10169   if (mat->ops->getlocalsubmatrix) {
10170     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10171   } else {
10172     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10173   }
10174   PetscFunctionReturn(0);
10175 }
10176 
10177 /*@
10178    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10179 
10180    Not Collective
10181 
10182    Input Arguments:
10183    mat - matrix to extract local submatrix from
10184    isrow - local row indices for submatrix
10185    iscol - local column indices for submatrix
10186    submat - the submatrix
10187 
10188    Level: intermediate
10189 
10190 .seealso: MatGetLocalSubMatrix()
10191 @*/
10192 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10193 {
10194   PetscErrorCode ierr;
10195 
10196   PetscFunctionBegin;
10197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10198   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10199   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10200   PetscCheckSameComm(isrow,2,iscol,3);
10201   PetscValidPointer(submat,4);
10202   if (*submat) {
10203     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10204   }
10205 
10206   if (mat->ops->restorelocalsubmatrix) {
10207     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10208   } else {
10209     ierr = MatDestroy(submat);CHKERRQ(ierr);
10210   }
10211   *submat = NULL;
10212   PetscFunctionReturn(0);
10213 }
10214 
10215 /* --------------------------------------------------------*/
10216 /*@
10217    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10218 
10219    Collective on Mat
10220 
10221    Input Parameter:
10222 .  mat - the matrix
10223 
10224    Output Parameter:
10225 .  is - if any rows have zero diagonals this contains the list of them
10226 
10227    Level: developer
10228 
10229 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10230 @*/
10231 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10232 {
10233   PetscErrorCode ierr;
10234 
10235   PetscFunctionBegin;
10236   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10237   PetscValidType(mat,1);
10238   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10239   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10240 
10241   if (!mat->ops->findzerodiagonals) {
10242     Vec                diag;
10243     const PetscScalar *a;
10244     PetscInt          *rows;
10245     PetscInt           rStart, rEnd, r, nrow = 0;
10246 
10247     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10248     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10249     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10250     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10251     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10252     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10253     nrow = 0;
10254     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10255     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10256     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10257     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10258   } else {
10259     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10260   }
10261   PetscFunctionReturn(0);
10262 }
10263 
10264 /*@
10265    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10266 
10267    Collective on Mat
10268 
10269    Input Parameter:
10270 .  mat - the matrix
10271 
10272    Output Parameter:
10273 .  is - contains the list of rows with off block diagonal entries
10274 
10275    Level: developer
10276 
10277 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10278 @*/
10279 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10280 {
10281   PetscErrorCode ierr;
10282 
10283   PetscFunctionBegin;
10284   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10285   PetscValidType(mat,1);
10286   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10287   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10288 
10289   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10290   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10291   PetscFunctionReturn(0);
10292 }
10293 
10294 /*@C
10295   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10296 
10297   Collective on Mat
10298 
10299   Input Parameters:
10300 . mat - the matrix
10301 
10302   Output Parameters:
10303 . values - the block inverses in column major order (FORTRAN-like)
10304 
10305    Note:
10306    This routine is not available from Fortran.
10307 
10308   Level: advanced
10309 
10310 .seealso: MatInvertBockDiagonalMat
10311 @*/
10312 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10313 {
10314   PetscErrorCode ierr;
10315 
10316   PetscFunctionBegin;
10317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10318   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10319   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10320   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10321   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10322   PetscFunctionReturn(0);
10323 }
10324 
10325 /*@C
10326   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10327 
10328   Collective on Mat
10329 
10330   Input Parameters:
10331 + mat - the matrix
10332 . nblocks - the number of blocks
10333 - bsizes - the size of each block
10334 
10335   Output Parameters:
10336 . values - the block inverses in column major order (FORTRAN-like)
10337 
10338    Note:
10339    This routine is not available from Fortran.
10340 
10341   Level: advanced
10342 
10343 .seealso: MatInvertBockDiagonal()
10344 @*/
10345 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10346 {
10347   PetscErrorCode ierr;
10348 
10349   PetscFunctionBegin;
10350   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10351   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10352   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10353   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10354   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10355   PetscFunctionReturn(0);
10356 }
10357 
10358 /*@
10359   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10360 
10361   Collective on Mat
10362 
10363   Input Parameters:
10364 . A - the matrix
10365 
10366   Output Parameters:
10367 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10368 
10369   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10370 
10371   Level: advanced
10372 
10373 .seealso: MatInvertBockDiagonal()
10374 @*/
10375 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10376 {
10377   PetscErrorCode     ierr;
10378   const PetscScalar *vals;
10379   PetscInt          *dnnz;
10380   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10381 
10382   PetscFunctionBegin;
10383   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10384   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10385   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10386   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10387   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10388   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10389   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10390   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10391   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10392   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10393   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10394   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10395   for (i = rstart/bs; i < rend/bs; i++) {
10396     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10397   }
10398   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10399   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10400   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10401   PetscFunctionReturn(0);
10402 }
10403 
10404 /*@C
10405     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10406     via MatTransposeColoringCreate().
10407 
10408     Collective on MatTransposeColoring
10409 
10410     Input Parameter:
10411 .   c - coloring context
10412 
10413     Level: intermediate
10414 
10415 .seealso: MatTransposeColoringCreate()
10416 @*/
10417 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10418 {
10419   PetscErrorCode       ierr;
10420   MatTransposeColoring matcolor=*c;
10421 
10422   PetscFunctionBegin;
10423   if (!matcolor) PetscFunctionReturn(0);
10424   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10425 
10426   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10427   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10428   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10429   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10430   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10431   if (matcolor->brows>0) {
10432     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10433   }
10434   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10435   PetscFunctionReturn(0);
10436 }
10437 
10438 /*@C
10439     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10440     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10441     MatTransposeColoring to sparse B.
10442 
10443     Collective on MatTransposeColoring
10444 
10445     Input Parameters:
10446 +   B - sparse matrix B
10447 .   Btdense - symbolic dense matrix B^T
10448 -   coloring - coloring context created with MatTransposeColoringCreate()
10449 
10450     Output Parameter:
10451 .   Btdense - dense matrix B^T
10452 
10453     Level: advanced
10454 
10455      Notes:
10456     These are used internally for some implementations of MatRARt()
10457 
10458 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10459 
10460 @*/
10461 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10462 {
10463   PetscErrorCode ierr;
10464 
10465   PetscFunctionBegin;
10466   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10467   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10468   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10469 
10470   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10471   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10472   PetscFunctionReturn(0);
10473 }
10474 
10475 /*@C
10476     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10477     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10478     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10479     Csp from Cden.
10480 
10481     Collective on MatTransposeColoring
10482 
10483     Input Parameters:
10484 +   coloring - coloring context created with MatTransposeColoringCreate()
10485 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10486 
10487     Output Parameter:
10488 .   Csp - sparse matrix
10489 
10490     Level: advanced
10491 
10492      Notes:
10493     These are used internally for some implementations of MatRARt()
10494 
10495 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10496 
10497 @*/
10498 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10499 {
10500   PetscErrorCode ierr;
10501 
10502   PetscFunctionBegin;
10503   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10504   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10505   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10506 
10507   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10508   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10509   PetscFunctionReturn(0);
10510 }
10511 
10512 /*@C
10513    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10514 
10515    Collective on Mat
10516 
10517    Input Parameters:
10518 +  mat - the matrix product C
10519 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10520 
10521     Output Parameter:
10522 .   color - the new coloring context
10523 
10524     Level: intermediate
10525 
10526 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10527            MatTransColoringApplyDenToSp()
10528 @*/
10529 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10530 {
10531   MatTransposeColoring c;
10532   MPI_Comm             comm;
10533   PetscErrorCode       ierr;
10534 
10535   PetscFunctionBegin;
10536   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10537   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10538   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10539 
10540   c->ctype = iscoloring->ctype;
10541   if (mat->ops->transposecoloringcreate) {
10542     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10543   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10544 
10545   *color = c;
10546   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10547   PetscFunctionReturn(0);
10548 }
10549 
10550 /*@
10551       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10552         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10553         same, otherwise it will be larger
10554 
10555      Not Collective
10556 
10557   Input Parameter:
10558 .    A  - the matrix
10559 
10560   Output Parameter:
10561 .    state - the current state
10562 
10563   Notes:
10564     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10565          different matrices
10566 
10567   Level: intermediate
10568 
10569 @*/
10570 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10571 {
10572   PetscFunctionBegin;
10573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10574   *state = mat->nonzerostate;
10575   PetscFunctionReturn(0);
10576 }
10577 
10578 /*@
10579       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10580                  matrices from each processor
10581 
10582     Collective
10583 
10584    Input Parameters:
10585 +    comm - the communicators the parallel matrix will live on
10586 .    seqmat - the input sequential matrices
10587 .    n - number of local columns (or PETSC_DECIDE)
10588 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10589 
10590    Output Parameter:
10591 .    mpimat - the parallel matrix generated
10592 
10593     Level: advanced
10594 
10595    Notes:
10596     The number of columns of the matrix in EACH processor MUST be the same.
10597 
10598 @*/
10599 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10600 {
10601   PetscErrorCode ierr;
10602 
10603   PetscFunctionBegin;
10604   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10605   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");
10606 
10607   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10608   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10609   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10610   PetscFunctionReturn(0);
10611 }
10612 
10613 /*@
10614      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10615                  ranks' ownership ranges.
10616 
10617     Collective on A
10618 
10619    Input Parameters:
10620 +    A   - the matrix to create subdomains from
10621 -    N   - requested number of subdomains
10622 
10623 
10624    Output Parameters:
10625 +    n   - number of subdomains resulting on this rank
10626 -    iss - IS list with indices of subdomains on this rank
10627 
10628     Level: advanced
10629 
10630     Notes:
10631     number of subdomains must be smaller than the communicator size
10632 @*/
10633 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10634 {
10635   MPI_Comm        comm,subcomm;
10636   PetscMPIInt     size,rank,color;
10637   PetscInt        rstart,rend,k;
10638   PetscErrorCode  ierr;
10639 
10640   PetscFunctionBegin;
10641   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10642   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10643   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10644   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);
10645   *n = 1;
10646   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10647   color = rank/k;
10648   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10649   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10650   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10651   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10652   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10653   PetscFunctionReturn(0);
10654 }
10655 
10656 /*@
10657    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10658 
10659    If the interpolation and restriction operators are the same, uses MatPtAP.
10660    If they are not the same, use MatMatMatMult.
10661 
10662    Once the coarse grid problem is constructed, correct for interpolation operators
10663    that are not of full rank, which can legitimately happen in the case of non-nested
10664    geometric multigrid.
10665 
10666    Input Parameters:
10667 +  restrct - restriction operator
10668 .  dA - fine grid matrix
10669 .  interpolate - interpolation operator
10670 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10671 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10672 
10673    Output Parameters:
10674 .  A - the Galerkin coarse matrix
10675 
10676    Options Database Key:
10677 .  -pc_mg_galerkin <both,pmat,mat,none>
10678 
10679    Level: developer
10680 
10681 .seealso: MatPtAP(), MatMatMatMult()
10682 @*/
10683 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10684 {
10685   PetscErrorCode ierr;
10686   IS             zerorows;
10687   Vec            diag;
10688 
10689   PetscFunctionBegin;
10690   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10691   /* Construct the coarse grid matrix */
10692   if (interpolate == restrct) {
10693     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10694   } else {
10695     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10696   }
10697 
10698   /* If the interpolation matrix is not of full rank, A will have zero rows.
10699      This can legitimately happen in the case of non-nested geometric multigrid.
10700      In that event, we set the rows of the matrix to the rows of the identity,
10701      ignoring the equations (as the RHS will also be zero). */
10702 
10703   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10704 
10705   if (zerorows != NULL) { /* if there are any zero rows */
10706     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10707     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10708     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10709     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10710     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10711     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10712   }
10713   PetscFunctionReturn(0);
10714 }
10715 
10716 /*@C
10717     MatSetOperation - Allows user to set a matrix operation for any matrix type
10718 
10719    Logically Collective on Mat
10720 
10721     Input Parameters:
10722 +   mat - the matrix
10723 .   op - the name of the operation
10724 -   f - the function that provides the operation
10725 
10726    Level: developer
10727 
10728     Usage:
10729 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10730 $      ierr = MatCreateXXX(comm,...&A);
10731 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10732 
10733     Notes:
10734     See the file include/petscmat.h for a complete list of matrix
10735     operations, which all have the form MATOP_<OPERATION>, where
10736     <OPERATION> is the name (in all capital letters) of the
10737     user interface routine (e.g., MatMult() -> MATOP_MULT).
10738 
10739     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10740     sequence as the usual matrix interface routines, since they
10741     are intended to be accessed via the usual matrix interface
10742     routines, e.g.,
10743 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10744 
10745     In particular each function MUST return an error code of 0 on success and
10746     nonzero on failure.
10747 
10748     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10749 
10750 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10751 @*/
10752 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10753 {
10754   PetscFunctionBegin;
10755   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10756   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10757     mat->ops->viewnative = mat->ops->view;
10758   }
10759   (((void(**)(void))mat->ops)[op]) = f;
10760   PetscFunctionReturn(0);
10761 }
10762 
10763 /*@C
10764     MatGetOperation - Gets a matrix operation for any matrix type.
10765 
10766     Not Collective
10767 
10768     Input Parameters:
10769 +   mat - the matrix
10770 -   op - the name of the operation
10771 
10772     Output Parameter:
10773 .   f - the function that provides the operation
10774 
10775     Level: developer
10776 
10777     Usage:
10778 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10779 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10780 
10781     Notes:
10782     See the file include/petscmat.h for a complete list of matrix
10783     operations, which all have the form MATOP_<OPERATION>, where
10784     <OPERATION> is the name (in all capital letters) of the
10785     user interface routine (e.g., MatMult() -> MATOP_MULT).
10786 
10787     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10788 
10789 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10790 @*/
10791 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10792 {
10793   PetscFunctionBegin;
10794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10795   *f = (((void (**)(void))mat->ops)[op]);
10796   PetscFunctionReturn(0);
10797 }
10798 
10799 /*@
10800     MatHasOperation - Determines whether the given matrix supports the particular
10801     operation.
10802 
10803    Not Collective
10804 
10805    Input Parameters:
10806 +  mat - the matrix
10807 -  op - the operation, for example, MATOP_GET_DIAGONAL
10808 
10809    Output Parameter:
10810 .  has - either PETSC_TRUE or PETSC_FALSE
10811 
10812    Level: advanced
10813 
10814    Notes:
10815    See the file include/petscmat.h for a complete list of matrix
10816    operations, which all have the form MATOP_<OPERATION>, where
10817    <OPERATION> is the name (in all capital letters) of the
10818    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10819 
10820 .seealso: MatCreateShell()
10821 @*/
10822 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10823 {
10824   PetscErrorCode ierr;
10825 
10826   PetscFunctionBegin;
10827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10828   PetscValidType(mat,1);
10829   PetscValidPointer(has,3);
10830   if (mat->ops->hasoperation) {
10831     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10832   } else {
10833     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10834     else {
10835       *has = PETSC_FALSE;
10836       if (op == MATOP_CREATE_SUBMATRIX) {
10837         PetscMPIInt size;
10838 
10839         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10840         if (size == 1) {
10841           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10842         }
10843       }
10844     }
10845   }
10846   PetscFunctionReturn(0);
10847 }
10848 
10849 /*@
10850     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10851     of the matrix are congruent
10852 
10853    Collective on mat
10854 
10855    Input Parameters:
10856 .  mat - the matrix
10857 
10858    Output Parameter:
10859 .  cong - either PETSC_TRUE or PETSC_FALSE
10860 
10861    Level: beginner
10862 
10863    Notes:
10864 
10865 .seealso: MatCreate(), MatSetSizes()
10866 @*/
10867 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10868 {
10869   PetscErrorCode ierr;
10870 
10871   PetscFunctionBegin;
10872   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10873   PetscValidType(mat,1);
10874   PetscValidPointer(cong,2);
10875   if (!mat->rmap || !mat->cmap) {
10876     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10877     PetscFunctionReturn(0);
10878   }
10879   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10880     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10881     if (*cong) mat->congruentlayouts = 1;
10882     else       mat->congruentlayouts = 0;
10883   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10884   PetscFunctionReturn(0);
10885 }
10886 
10887 /*@
10888     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
10889     e.g., matrx product of MatPtAP.
10890 
10891    Collective on mat
10892 
10893    Input Parameters:
10894 .  mat - the matrix
10895 
10896    Output Parameter:
10897 .  mat - the matrix with intermediate data structures released
10898 
10899    Level: advanced
10900 
10901    Notes:
10902 
10903 .seealso: MatPtAP(), MatMatMult()
10904 @*/
10905 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
10906 {
10907   PetscErrorCode ierr;
10908 
10909   PetscFunctionBegin;
10910   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10911   PetscValidType(mat,1);
10912   if (mat->ops->freeintermediatedatastructures) {
10913     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
10914   }
10915   PetscFunctionReturn(0);
10916 }
10917