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