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