xref: /petsc/src/mat/interface/matrix.c (revision 080f0011773203ad8803837596fa1e3f25ef47ae)
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           PetscFunctionReturn(0);
4150         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4151           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4152           PetscFunctionReturn(0);
4153         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4154           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4155           PetscFunctionReturn(0);
4156         }
4157       }
4158     }
4159     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4160     for (i=0; i<3; i++) {
4161       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4162       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4163       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4164       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4165       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4166       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4167       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4168       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4169       if (conv) goto foundconv;
4170     }
4171 
4172     /* 2)  See if a specialized converter is known to the desired matrix class. */
4173     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4174     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4175     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4176     for (i=0; i<3; i++) {
4177       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4178       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4179       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4180       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4181       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4182       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4183       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4184       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4185       if (conv) {
4186         ierr = MatDestroy(&B);CHKERRQ(ierr);
4187         goto foundconv;
4188       }
4189     }
4190 
4191     /* 3) See if a good general converter is registered for the desired class */
4192     conv = B->ops->convertfrom;
4193     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4194     ierr = MatDestroy(&B);CHKERRQ(ierr);
4195     if (conv) goto foundconv;
4196 
4197     /* 4) See if a good general converter is known for the current matrix */
4198     if (mat->ops->convert) conv = mat->ops->convert;
4199 
4200     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4201     if (conv) goto foundconv;
4202 
4203     /* 5) Use a really basic converter. */
4204     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4205     conv = MatConvert_Basic;
4206 
4207 foundconv:
4208     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4209     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4210     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4211       /* the block sizes must be same if the mappings are copied over */
4212       (*M)->rmap->bs = mat->rmap->bs;
4213       (*M)->cmap->bs = mat->cmap->bs;
4214       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4215       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4216       (*M)->rmap->mapping = mat->rmap->mapping;
4217       (*M)->cmap->mapping = mat->cmap->mapping;
4218     }
4219     (*M)->stencil.dim = mat->stencil.dim;
4220     (*M)->stencil.noc = mat->stencil.noc;
4221     for (i=0; i<=mat->stencil.dim; i++) {
4222       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4223       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4224     }
4225     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4226   }
4227   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4228 
4229   /* Copy Mat options */
4230   if (issymmetric) {
4231     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4232   }
4233   if (ishermitian) {
4234     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4235   }
4236   PetscFunctionReturn(0);
4237 }
4238 
4239 /*@C
4240    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4241 
4242    Not Collective
4243 
4244    Input Parameter:
4245 .  mat - the matrix, must be a factored matrix
4246 
4247    Output Parameter:
4248 .   type - the string name of the package (do not free this string)
4249 
4250    Notes:
4251       In Fortran you pass in a empty string and the package name will be copied into it.
4252     (Make sure the string is long enough)
4253 
4254    Level: intermediate
4255 
4256 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4257 @*/
4258 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4259 {
4260   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4261 
4262   PetscFunctionBegin;
4263   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4264   PetscValidType(mat,1);
4265   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4266   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4267   if (!conv) {
4268     *type = MATSOLVERPETSC;
4269   } else {
4270     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4271   }
4272   PetscFunctionReturn(0);
4273 }
4274 
4275 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4276 struct _MatSolverTypeForSpecifcType {
4277   MatType                        mtype;
4278   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4279   MatSolverTypeForSpecifcType next;
4280 };
4281 
4282 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4283 struct _MatSolverTypeHolder {
4284   char                           *name;
4285   MatSolverTypeForSpecifcType handlers;
4286   MatSolverTypeHolder         next;
4287 };
4288 
4289 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4290 
4291 /*@C
4292    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4293 
4294    Input Parameters:
4295 +    package - name of the package, for example petsc or superlu
4296 .    mtype - the matrix type that works with this package
4297 .    ftype - the type of factorization supported by the package
4298 -    getfactor - routine that will create the factored matrix ready to be used
4299 
4300     Level: intermediate
4301 
4302 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4303 @*/
4304 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4305 {
4306   PetscErrorCode              ierr;
4307   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4308   PetscBool                   flg;
4309   MatSolverTypeForSpecifcType inext,iprev = NULL;
4310 
4311   PetscFunctionBegin;
4312   ierr = MatInitializePackage();CHKERRQ(ierr);
4313   if (!next) {
4314     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4315     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4316     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4317     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4318     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4319     PetscFunctionReturn(0);
4320   }
4321   while (next) {
4322     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4323     if (flg) {
4324       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4325       inext = next->handlers;
4326       while (inext) {
4327         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4328         if (flg) {
4329           inext->getfactor[(int)ftype-1] = getfactor;
4330           PetscFunctionReturn(0);
4331         }
4332         iprev = inext;
4333         inext = inext->next;
4334       }
4335       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4336       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4337       iprev->next->getfactor[(int)ftype-1] = getfactor;
4338       PetscFunctionReturn(0);
4339     }
4340     prev = next;
4341     next = next->next;
4342   }
4343   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4344   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4345   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4346   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4347   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4348   PetscFunctionReturn(0);
4349 }
4350 
4351 /*@C
4352    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4353 
4354    Input Parameters:
4355 +    package - name of the package, for example petsc or superlu
4356 .    ftype - the type of factorization supported by the package
4357 -    mtype - the matrix type that works with this package
4358 
4359    Output Parameters:
4360 +   foundpackage - PETSC_TRUE if the package was registered
4361 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4362 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4363 
4364     Level: intermediate
4365 
4366 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4367 @*/
4368 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4369 {
4370   PetscErrorCode              ierr;
4371   MatSolverTypeHolder         next = MatSolverTypeHolders;
4372   PetscBool                   flg;
4373   MatSolverTypeForSpecifcType inext;
4374 
4375   PetscFunctionBegin;
4376   if (foundpackage) *foundpackage = PETSC_FALSE;
4377   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4378   if (getfactor)    *getfactor    = NULL;
4379 
4380   if (package) {
4381     while (next) {
4382       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4383       if (flg) {
4384         if (foundpackage) *foundpackage = PETSC_TRUE;
4385         inext = next->handlers;
4386         while (inext) {
4387           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4388           if (flg) {
4389             if (foundmtype) *foundmtype = PETSC_TRUE;
4390             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4391             PetscFunctionReturn(0);
4392           }
4393           inext = inext->next;
4394         }
4395       }
4396       next = next->next;
4397     }
4398   } else {
4399     while (next) {
4400       inext = next->handlers;
4401       while (inext) {
4402         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4403         if (flg && inext->getfactor[(int)ftype-1]) {
4404           if (foundpackage) *foundpackage = PETSC_TRUE;
4405           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4406           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4407           PetscFunctionReturn(0);
4408         }
4409         inext = inext->next;
4410       }
4411       next = next->next;
4412     }
4413   }
4414   PetscFunctionReturn(0);
4415 }
4416 
4417 PetscErrorCode MatSolverTypeDestroy(void)
4418 {
4419   PetscErrorCode              ierr;
4420   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4421   MatSolverTypeForSpecifcType inext,iprev;
4422 
4423   PetscFunctionBegin;
4424   while (next) {
4425     ierr = PetscFree(next->name);CHKERRQ(ierr);
4426     inext = next->handlers;
4427     while (inext) {
4428       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4429       iprev = inext;
4430       inext = inext->next;
4431       ierr = PetscFree(iprev);CHKERRQ(ierr);
4432     }
4433     prev = next;
4434     next = next->next;
4435     ierr = PetscFree(prev);CHKERRQ(ierr);
4436   }
4437   MatSolverTypeHolders = NULL;
4438   PetscFunctionReturn(0);
4439 }
4440 
4441 /*@C
4442    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4443 
4444    Collective on Mat
4445 
4446    Input Parameters:
4447 +  mat - the matrix
4448 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4449 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4450 
4451    Output Parameters:
4452 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4453 
4454    Notes:
4455       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4456      such as pastix, superlu, mumps etc.
4457 
4458       PETSc must have been ./configure to use the external solver, using the option --download-package
4459 
4460    Level: intermediate
4461 
4462 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4463 @*/
4464 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4465 {
4466   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4467   PetscBool      foundpackage,foundmtype;
4468 
4469   PetscFunctionBegin;
4470   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4471   PetscValidType(mat,1);
4472 
4473   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4474   MatCheckPreallocated(mat,1);
4475 
4476   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4477   if (!foundpackage) {
4478     if (type) {
4479       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);
4480     } else {
4481       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);
4482     }
4483   }
4484   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4485   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);
4486 
4487   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4488   PetscFunctionReturn(0);
4489 }
4490 
4491 /*@C
4492    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4493 
4494    Not Collective
4495 
4496    Input Parameters:
4497 +  mat - the matrix
4498 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4499 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4500 
4501    Output Parameter:
4502 .    flg - PETSC_TRUE if the factorization is available
4503 
4504    Notes:
4505       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4506      such as pastix, superlu, mumps etc.
4507 
4508       PETSc must have been ./configure to use the external solver, using the option --download-package
4509 
4510    Level: intermediate
4511 
4512 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4513 @*/
4514 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4515 {
4516   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4517 
4518   PetscFunctionBegin;
4519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4520   PetscValidType(mat,1);
4521 
4522   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4523   MatCheckPreallocated(mat,1);
4524 
4525   *flg = PETSC_FALSE;
4526   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4527   if (gconv) {
4528     *flg = PETSC_TRUE;
4529   }
4530   PetscFunctionReturn(0);
4531 }
4532 
4533 #include <petscdmtypes.h>
4534 
4535 /*@
4536    MatDuplicate - Duplicates a matrix including the non-zero structure.
4537 
4538    Collective on Mat
4539 
4540    Input Parameters:
4541 +  mat - the matrix
4542 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4543         See the manual page for MatDuplicateOption for an explanation of these options.
4544 
4545    Output Parameter:
4546 .  M - pointer to place new matrix
4547 
4548    Level: intermediate
4549 
4550    Notes:
4551     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4552     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.
4553 
4554 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4555 @*/
4556 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4557 {
4558   PetscErrorCode ierr;
4559   Mat            B;
4560   PetscInt       i;
4561   DM             dm;
4562   void           (*viewf)(void);
4563 
4564   PetscFunctionBegin;
4565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4566   PetscValidType(mat,1);
4567   PetscValidPointer(M,3);
4568   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4569   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4570   MatCheckPreallocated(mat,1);
4571 
4572   *M = 0;
4573   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4574   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4575   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4576   B    = *M;
4577 
4578   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4579   if (viewf) {
4580     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4581   }
4582 
4583   B->stencil.dim = mat->stencil.dim;
4584   B->stencil.noc = mat->stencil.noc;
4585   for (i=0; i<=mat->stencil.dim; i++) {
4586     B->stencil.dims[i]   = mat->stencil.dims[i];
4587     B->stencil.starts[i] = mat->stencil.starts[i];
4588   }
4589 
4590   B->nooffproczerorows = mat->nooffproczerorows;
4591   B->nooffprocentries  = mat->nooffprocentries;
4592 
4593   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4594   if (dm) {
4595     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4596   }
4597   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4598   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4599   PetscFunctionReturn(0);
4600 }
4601 
4602 /*@
4603    MatGetDiagonal - Gets the diagonal of a matrix.
4604 
4605    Logically Collective on Mat
4606 
4607    Input Parameters:
4608 +  mat - the matrix
4609 -  v - the vector for storing the diagonal
4610 
4611    Output Parameter:
4612 .  v - the diagonal of the matrix
4613 
4614    Level: intermediate
4615 
4616    Note:
4617    Currently only correct in parallel for square matrices.
4618 
4619 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4620 @*/
4621 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4622 {
4623   PetscErrorCode ierr;
4624 
4625   PetscFunctionBegin;
4626   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4627   PetscValidType(mat,1);
4628   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4629   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4630   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4631   MatCheckPreallocated(mat,1);
4632 
4633   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4634   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4635   PetscFunctionReturn(0);
4636 }
4637 
4638 /*@C
4639    MatGetRowMin - Gets the minimum value (of the real part) of each
4640         row of the matrix
4641 
4642    Logically Collective on Mat
4643 
4644    Input Parameters:
4645 .  mat - the matrix
4646 
4647    Output Parameter:
4648 +  v - the vector for storing the maximums
4649 -  idx - the indices of the column found for each row (optional)
4650 
4651    Level: intermediate
4652 
4653    Notes:
4654     The result of this call are the same as if one converted the matrix to dense format
4655       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4656 
4657     This code is only implemented for a couple of matrix formats.
4658 
4659 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4660           MatGetRowMax()
4661 @*/
4662 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4663 {
4664   PetscErrorCode ierr;
4665 
4666   PetscFunctionBegin;
4667   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4668   PetscValidType(mat,1);
4669   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4670   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4671   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4672   MatCheckPreallocated(mat,1);
4673 
4674   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4675   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4676   PetscFunctionReturn(0);
4677 }
4678 
4679 /*@C
4680    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4681         row of the matrix
4682 
4683    Logically Collective on Mat
4684 
4685    Input Parameters:
4686 .  mat - the matrix
4687 
4688    Output Parameter:
4689 +  v - the vector for storing the minimums
4690 -  idx - the indices of the column found for each row (or NULL if not needed)
4691 
4692    Level: intermediate
4693 
4694    Notes:
4695     if a row is completely empty or has only 0.0 values then the idx[] value for that
4696     row is 0 (the first column).
4697 
4698     This code is only implemented for a couple of matrix formats.
4699 
4700 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4701 @*/
4702 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4703 {
4704   PetscErrorCode ierr;
4705 
4706   PetscFunctionBegin;
4707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4708   PetscValidType(mat,1);
4709   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4710   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4711   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4712   MatCheckPreallocated(mat,1);
4713   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4714 
4715   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4716   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4717   PetscFunctionReturn(0);
4718 }
4719 
4720 /*@C
4721    MatGetRowMax - Gets the maximum value (of the real part) of each
4722         row of the matrix
4723 
4724    Logically Collective on Mat
4725 
4726    Input Parameters:
4727 .  mat - the matrix
4728 
4729    Output Parameter:
4730 +  v - the vector for storing the maximums
4731 -  idx - the indices of the column found for each row (optional)
4732 
4733    Level: intermediate
4734 
4735    Notes:
4736     The result of this call are the same as if one converted the matrix to dense format
4737       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4738 
4739     This code is only implemented for a couple of matrix formats.
4740 
4741 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4742 @*/
4743 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4744 {
4745   PetscErrorCode ierr;
4746 
4747   PetscFunctionBegin;
4748   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4749   PetscValidType(mat,1);
4750   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4751   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4752   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4753   MatCheckPreallocated(mat,1);
4754 
4755   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4756   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4757   PetscFunctionReturn(0);
4758 }
4759 
4760 /*@C
4761    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4762         row of the matrix
4763 
4764    Logically Collective on Mat
4765 
4766    Input Parameters:
4767 .  mat - the matrix
4768 
4769    Output Parameter:
4770 +  v - the vector for storing the maximums
4771 -  idx - the indices of the column found for each row (or NULL if not needed)
4772 
4773    Level: intermediate
4774 
4775    Notes:
4776     if a row is completely empty or has only 0.0 values then the idx[] value for that
4777     row is 0 (the first column).
4778 
4779     This code is only implemented for a couple of matrix formats.
4780 
4781 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4782 @*/
4783 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4784 {
4785   PetscErrorCode ierr;
4786 
4787   PetscFunctionBegin;
4788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4789   PetscValidType(mat,1);
4790   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4791   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4792   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4793   MatCheckPreallocated(mat,1);
4794   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4795 
4796   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4797   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4798   PetscFunctionReturn(0);
4799 }
4800 
4801 /*@
4802    MatGetRowSum - Gets the sum of each row of the matrix
4803 
4804    Logically or Neighborhood Collective on Mat
4805 
4806    Input Parameters:
4807 .  mat - the matrix
4808 
4809    Output Parameter:
4810 .  v - the vector for storing the sum of rows
4811 
4812    Level: intermediate
4813 
4814    Notes:
4815     This code is slow since it is not currently specialized for different formats
4816 
4817 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4818 @*/
4819 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4820 {
4821   Vec            ones;
4822   PetscErrorCode ierr;
4823 
4824   PetscFunctionBegin;
4825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4826   PetscValidType(mat,1);
4827   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4828   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4829   MatCheckPreallocated(mat,1);
4830   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4831   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4832   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4833   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4834   PetscFunctionReturn(0);
4835 }
4836 
4837 /*@
4838    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4839 
4840    Collective on Mat
4841 
4842    Input Parameter:
4843 +  mat - the matrix to transpose
4844 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4845 
4846    Output Parameters:
4847 .  B - the transpose
4848 
4849    Notes:
4850      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4851 
4852      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4853 
4854      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4855 
4856    Level: intermediate
4857 
4858 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4859 @*/
4860 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4861 {
4862   PetscErrorCode ierr;
4863 
4864   PetscFunctionBegin;
4865   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4866   PetscValidType(mat,1);
4867   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4868   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4869   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4870   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4871   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4872   MatCheckPreallocated(mat,1);
4873 
4874   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4875   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4876   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4877   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4878   PetscFunctionReturn(0);
4879 }
4880 
4881 /*@
4882    MatIsTranspose - Test whether a matrix is another one's transpose,
4883         or its own, in which case it tests symmetry.
4884 
4885    Collective on Mat
4886 
4887    Input Parameter:
4888 +  A - the matrix to test
4889 -  B - the matrix to test against, this can equal the first parameter
4890 
4891    Output Parameters:
4892 .  flg - the result
4893 
4894    Notes:
4895    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4896    has a running time of the order of the number of nonzeros; the parallel
4897    test involves parallel copies of the block-offdiagonal parts of the matrix.
4898 
4899    Level: intermediate
4900 
4901 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4902 @*/
4903 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4904 {
4905   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4906 
4907   PetscFunctionBegin;
4908   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4909   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4910   PetscValidBoolPointer(flg,3);
4911   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4912   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4913   *flg = PETSC_FALSE;
4914   if (f && g) {
4915     if (f == g) {
4916       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4917     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4918   } else {
4919     MatType mattype;
4920     if (!f) {
4921       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4922     } else {
4923       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4924     }
4925     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
4926   }
4927   PetscFunctionReturn(0);
4928 }
4929 
4930 /*@
4931    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4932 
4933    Collective on Mat
4934 
4935    Input Parameter:
4936 +  mat - the matrix to transpose and complex conjugate
4937 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4938 
4939    Output Parameters:
4940 .  B - the Hermitian
4941 
4942    Level: intermediate
4943 
4944 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4945 @*/
4946 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4947 {
4948   PetscErrorCode ierr;
4949 
4950   PetscFunctionBegin;
4951   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4952 #if defined(PETSC_USE_COMPLEX)
4953   ierr = MatConjugate(*B);CHKERRQ(ierr);
4954 #endif
4955   PetscFunctionReturn(0);
4956 }
4957 
4958 /*@
4959    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4960 
4961    Collective on Mat
4962 
4963    Input Parameter:
4964 +  A - the matrix to test
4965 -  B - the matrix to test against, this can equal the first parameter
4966 
4967    Output Parameters:
4968 .  flg - the result
4969 
4970    Notes:
4971    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4972    has a running time of the order of the number of nonzeros; the parallel
4973    test involves parallel copies of the block-offdiagonal parts of the matrix.
4974 
4975    Level: intermediate
4976 
4977 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4978 @*/
4979 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4980 {
4981   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4982 
4983   PetscFunctionBegin;
4984   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4985   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4986   PetscValidBoolPointer(flg,3);
4987   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4988   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4989   if (f && g) {
4990     if (f==g) {
4991       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4992     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4993   }
4994   PetscFunctionReturn(0);
4995 }
4996 
4997 /*@
4998    MatPermute - Creates a new matrix with rows and columns permuted from the
4999    original.
5000 
5001    Collective on Mat
5002 
5003    Input Parameters:
5004 +  mat - the matrix to permute
5005 .  row - row permutation, each processor supplies only the permutation for its rows
5006 -  col - column permutation, each processor supplies only the permutation for its columns
5007 
5008    Output Parameters:
5009 .  B - the permuted matrix
5010 
5011    Level: advanced
5012 
5013    Note:
5014    The index sets map from row/col of permuted matrix to row/col of original matrix.
5015    The index sets should be on the same communicator as Mat and have the same local sizes.
5016 
5017 .seealso: MatGetOrdering(), ISAllGather()
5018 
5019 @*/
5020 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5021 {
5022   PetscErrorCode ierr;
5023 
5024   PetscFunctionBegin;
5025   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5026   PetscValidType(mat,1);
5027   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5028   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5029   PetscValidPointer(B,4);
5030   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5031   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5032   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5033   MatCheckPreallocated(mat,1);
5034 
5035   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5036   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5037   PetscFunctionReturn(0);
5038 }
5039 
5040 /*@
5041    MatEqual - Compares two matrices.
5042 
5043    Collective on Mat
5044 
5045    Input Parameters:
5046 +  A - the first matrix
5047 -  B - the second matrix
5048 
5049    Output Parameter:
5050 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5051 
5052    Level: intermediate
5053 
5054 @*/
5055 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5056 {
5057   PetscErrorCode ierr;
5058 
5059   PetscFunctionBegin;
5060   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5061   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5062   PetscValidType(A,1);
5063   PetscValidType(B,2);
5064   PetscValidBoolPointer(flg,3);
5065   PetscCheckSameComm(A,1,B,2);
5066   MatCheckPreallocated(B,2);
5067   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5068   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5069   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);
5070   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5071   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5072   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);
5073   MatCheckPreallocated(A,1);
5074 
5075   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5076   PetscFunctionReturn(0);
5077 }
5078 
5079 /*@
5080    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5081    matrices that are stored as vectors.  Either of the two scaling
5082    matrices can be NULL.
5083 
5084    Collective on Mat
5085 
5086    Input Parameters:
5087 +  mat - the matrix to be scaled
5088 .  l - the left scaling vector (or NULL)
5089 -  r - the right scaling vector (or NULL)
5090 
5091    Notes:
5092    MatDiagonalScale() computes A = LAR, where
5093    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5094    The L scales the rows of the matrix, the R scales the columns of the matrix.
5095 
5096    Level: intermediate
5097 
5098 
5099 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5100 @*/
5101 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5102 {
5103   PetscErrorCode ierr;
5104 
5105   PetscFunctionBegin;
5106   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5107   PetscValidType(mat,1);
5108   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5109   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5110   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5111   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5112   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5113   MatCheckPreallocated(mat,1);
5114 
5115   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5116   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5117   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5118   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5119   PetscFunctionReturn(0);
5120 }
5121 
5122 /*@
5123     MatScale - Scales all elements of a matrix by a given number.
5124 
5125     Logically Collective on Mat
5126 
5127     Input Parameters:
5128 +   mat - the matrix to be scaled
5129 -   a  - the scaling value
5130 
5131     Output Parameter:
5132 .   mat - the scaled matrix
5133 
5134     Level: intermediate
5135 
5136 .seealso: MatDiagonalScale()
5137 @*/
5138 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5139 {
5140   PetscErrorCode ierr;
5141 
5142   PetscFunctionBegin;
5143   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5144   PetscValidType(mat,1);
5145   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5146   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5147   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5148   PetscValidLogicalCollectiveScalar(mat,a,2);
5149   MatCheckPreallocated(mat,1);
5150 
5151   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5152   if (a != (PetscScalar)1.0) {
5153     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5154     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5155   }
5156   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5157   PetscFunctionReturn(0);
5158 }
5159 
5160 /*@
5161    MatNorm - Calculates various norms of a matrix.
5162 
5163    Collective on Mat
5164 
5165    Input Parameters:
5166 +  mat - the matrix
5167 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5168 
5169    Output Parameters:
5170 .  nrm - the resulting norm
5171 
5172    Level: intermediate
5173 
5174 @*/
5175 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5176 {
5177   PetscErrorCode ierr;
5178 
5179   PetscFunctionBegin;
5180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5181   PetscValidType(mat,1);
5182   PetscValidScalarPointer(nrm,3);
5183 
5184   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5185   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5186   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5187   MatCheckPreallocated(mat,1);
5188 
5189   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5190   PetscFunctionReturn(0);
5191 }
5192 
5193 /*
5194      This variable is used to prevent counting of MatAssemblyBegin() that
5195    are called from within a MatAssemblyEnd().
5196 */
5197 static PetscInt MatAssemblyEnd_InUse = 0;
5198 /*@
5199    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5200    be called after completing all calls to MatSetValues().
5201 
5202    Collective on Mat
5203 
5204    Input Parameters:
5205 +  mat - the matrix
5206 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5207 
5208    Notes:
5209    MatSetValues() generally caches the values.  The matrix is ready to
5210    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5211    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5212    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5213    using the matrix.
5214 
5215    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5216    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
5217    a global collective operation requring all processes that share the matrix.
5218 
5219    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5220    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5221    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5222 
5223    Level: beginner
5224 
5225 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5226 @*/
5227 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5228 {
5229   PetscErrorCode ierr;
5230 
5231   PetscFunctionBegin;
5232   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5233   PetscValidType(mat,1);
5234   MatCheckPreallocated(mat,1);
5235   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5236   if (mat->assembled) {
5237     mat->was_assembled = PETSC_TRUE;
5238     mat->assembled     = PETSC_FALSE;
5239   }
5240 
5241   if (!MatAssemblyEnd_InUse) {
5242     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5243     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5244     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5245   } else if (mat->ops->assemblybegin) {
5246     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5247   }
5248   PetscFunctionReturn(0);
5249 }
5250 
5251 /*@
5252    MatAssembled - Indicates if a matrix has been assembled and is ready for
5253      use; for example, in matrix-vector product.
5254 
5255    Not Collective
5256 
5257    Input Parameter:
5258 .  mat - the matrix
5259 
5260    Output Parameter:
5261 .  assembled - PETSC_TRUE or PETSC_FALSE
5262 
5263    Level: advanced
5264 
5265 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5266 @*/
5267 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5268 {
5269   PetscFunctionBegin;
5270   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5271   PetscValidPointer(assembled,2);
5272   *assembled = mat->assembled;
5273   PetscFunctionReturn(0);
5274 }
5275 
5276 /*@
5277    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5278    be called after MatAssemblyBegin().
5279 
5280    Collective on Mat
5281 
5282    Input Parameters:
5283 +  mat - the matrix
5284 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5285 
5286    Options Database Keys:
5287 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5288 .  -mat_view ::ascii_info_detail - Prints more detailed info
5289 .  -mat_view - Prints matrix in ASCII format
5290 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5291 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5292 .  -display <name> - Sets display name (default is host)
5293 .  -draw_pause <sec> - Sets number of seconds to pause after display
5294 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5295 .  -viewer_socket_machine <machine> - Machine to use for socket
5296 .  -viewer_socket_port <port> - Port number to use for socket
5297 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5298 
5299    Notes:
5300    MatSetValues() generally caches the values.  The matrix is ready to
5301    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5302    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5303    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5304    using the matrix.
5305 
5306    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5307    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5308    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5309 
5310    Level: beginner
5311 
5312 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5313 @*/
5314 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5315 {
5316   PetscErrorCode  ierr;
5317   static PetscInt inassm = 0;
5318   PetscBool       flg    = PETSC_FALSE;
5319 
5320   PetscFunctionBegin;
5321   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5322   PetscValidType(mat,1);
5323 
5324   inassm++;
5325   MatAssemblyEnd_InUse++;
5326   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5327     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5328     if (mat->ops->assemblyend) {
5329       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5330     }
5331     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5332   } else if (mat->ops->assemblyend) {
5333     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5334   }
5335 
5336   /* Flush assembly is not a true assembly */
5337   if (type != MAT_FLUSH_ASSEMBLY) {
5338     mat->num_ass++;
5339     mat->assembled        = PETSC_TRUE;
5340     mat->ass_nonzerostate = mat->nonzerostate;
5341   }
5342 
5343   mat->insertmode = NOT_SET_VALUES;
5344   MatAssemblyEnd_InUse--;
5345   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5346   if (!mat->symmetric_eternal) {
5347     mat->symmetric_set              = PETSC_FALSE;
5348     mat->hermitian_set              = PETSC_FALSE;
5349     mat->structurally_symmetric_set = PETSC_FALSE;
5350   }
5351   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5352     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5353 
5354     if (mat->checksymmetryonassembly) {
5355       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5356       if (flg) {
5357         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5358       } else {
5359         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5360       }
5361     }
5362     if (mat->nullsp && mat->checknullspaceonassembly) {
5363       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5364     }
5365   }
5366   inassm--;
5367   PetscFunctionReturn(0);
5368 }
5369 
5370 /*@
5371    MatSetOption - Sets a parameter option for a matrix. Some options
5372    may be specific to certain storage formats.  Some options
5373    determine how values will be inserted (or added). Sorted,
5374    row-oriented input will generally assemble the fastest. The default
5375    is row-oriented.
5376 
5377    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5378 
5379    Input Parameters:
5380 +  mat - the matrix
5381 .  option - the option, one of those listed below (and possibly others),
5382 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5383 
5384   Options Describing Matrix Structure:
5385 +    MAT_SPD - symmetric positive definite
5386 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5387 .    MAT_HERMITIAN - transpose is the complex conjugation
5388 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5389 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5390                             you set to be kept with all future use of the matrix
5391                             including after MatAssemblyBegin/End() which could
5392                             potentially change the symmetry structure, i.e. you
5393                             KNOW the matrix will ALWAYS have the property you set.
5394                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5395                             the relevant flags must be set independently.
5396 
5397 
5398    Options For Use with MatSetValues():
5399    Insert a logically dense subblock, which can be
5400 .    MAT_ROW_ORIENTED - row-oriented (default)
5401 
5402    Note these options reflect the data you pass in with MatSetValues(); it has
5403    nothing to do with how the data is stored internally in the matrix
5404    data structure.
5405 
5406    When (re)assembling a matrix, we can restrict the input for
5407    efficiency/debugging purposes.  These options include:
5408 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5409 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5410 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5411 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5412 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5413 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5414         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5415         performance for very large process counts.
5416 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5417         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5418         functions, instead sending only neighbor messages.
5419 
5420    Notes:
5421    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5422 
5423    Some options are relevant only for particular matrix types and
5424    are thus ignored by others.  Other options are not supported by
5425    certain matrix types and will generate an error message if set.
5426 
5427    If using a Fortran 77 module to compute a matrix, one may need to
5428    use the column-oriented option (or convert to the row-oriented
5429    format).
5430 
5431    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5432    that would generate a new entry in the nonzero structure is instead
5433    ignored.  Thus, if memory has not alredy been allocated for this particular
5434    data, then the insertion is ignored. For dense matrices, in which
5435    the entire array is allocated, no entries are ever ignored.
5436    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5437 
5438    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5439    that would generate a new entry in the nonzero structure instead produces
5440    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
5441 
5442    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5443    that would generate a new entry that has not been preallocated will
5444    instead produce an error. (Currently supported for AIJ and BAIJ formats
5445    only.) This is a useful flag when debugging matrix memory preallocation.
5446    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5447 
5448    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5449    other processors should be dropped, rather than stashed.
5450    This is useful if you know that the "owning" processor is also
5451    always generating the correct matrix entries, so that PETSc need
5452    not transfer duplicate entries generated on another processor.
5453 
5454    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5455    searches during matrix assembly. When this flag is set, the hash table
5456    is created during the first Matrix Assembly. This hash table is
5457    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5458    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5459    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5460    supported by MATMPIBAIJ format only.
5461 
5462    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5463    are kept in the nonzero structure
5464 
5465    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5466    a zero location in the matrix
5467 
5468    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5469 
5470    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5471         zero row routines and thus improves performance for very large process counts.
5472 
5473    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5474         part of the matrix (since they should match the upper triangular part).
5475 
5476    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5477                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5478                      with finite difference schemes with non-periodic boundary conditions.
5479    Notes:
5480     Can only be called after MatSetSizes() and MatSetType() have been set.
5481 
5482    Level: intermediate
5483 
5484 .seealso:  MatOption, Mat
5485 
5486 @*/
5487 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5488 {
5489   PetscErrorCode ierr;
5490 
5491   PetscFunctionBegin;
5492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5493   PetscValidType(mat,1);
5494   if (op > 0) {
5495     PetscValidLogicalCollectiveEnum(mat,op,2);
5496     PetscValidLogicalCollectiveBool(mat,flg,3);
5497   }
5498 
5499   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);
5500   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()");
5501 
5502   switch (op) {
5503   case MAT_NO_OFF_PROC_ENTRIES:
5504     mat->nooffprocentries = flg;
5505     PetscFunctionReturn(0);
5506     break;
5507   case MAT_SUBSET_OFF_PROC_ENTRIES:
5508     mat->assembly_subset = flg;
5509     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5510 #if !defined(PETSC_HAVE_MPIUNI)
5511       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5512 #endif
5513       mat->stash.first_assembly_done = PETSC_FALSE;
5514     }
5515     PetscFunctionReturn(0);
5516   case MAT_NO_OFF_PROC_ZERO_ROWS:
5517     mat->nooffproczerorows = flg;
5518     PetscFunctionReturn(0);
5519     break;
5520   case MAT_SPD:
5521     mat->spd_set = PETSC_TRUE;
5522     mat->spd     = flg;
5523     if (flg) {
5524       mat->symmetric                  = PETSC_TRUE;
5525       mat->structurally_symmetric     = PETSC_TRUE;
5526       mat->symmetric_set              = PETSC_TRUE;
5527       mat->structurally_symmetric_set = PETSC_TRUE;
5528     }
5529     break;
5530   case MAT_SYMMETRIC:
5531     mat->symmetric = flg;
5532     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5533     mat->symmetric_set              = PETSC_TRUE;
5534     mat->structurally_symmetric_set = flg;
5535 #if !defined(PETSC_USE_COMPLEX)
5536     mat->hermitian     = flg;
5537     mat->hermitian_set = PETSC_TRUE;
5538 #endif
5539     break;
5540   case MAT_HERMITIAN:
5541     mat->hermitian = flg;
5542     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5543     mat->hermitian_set              = PETSC_TRUE;
5544     mat->structurally_symmetric_set = flg;
5545 #if !defined(PETSC_USE_COMPLEX)
5546     mat->symmetric     = flg;
5547     mat->symmetric_set = PETSC_TRUE;
5548 #endif
5549     break;
5550   case MAT_STRUCTURALLY_SYMMETRIC:
5551     mat->structurally_symmetric     = flg;
5552     mat->structurally_symmetric_set = PETSC_TRUE;
5553     break;
5554   case MAT_SYMMETRY_ETERNAL:
5555     mat->symmetric_eternal = flg;
5556     break;
5557   case MAT_STRUCTURE_ONLY:
5558     mat->structure_only = flg;
5559     break;
5560   case MAT_SORTED_FULL:
5561     mat->sortedfull = flg;
5562     break;
5563   default:
5564     break;
5565   }
5566   if (mat->ops->setoption) {
5567     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5568   }
5569   PetscFunctionReturn(0);
5570 }
5571 
5572 /*@
5573    MatGetOption - Gets a parameter option that has been set for a matrix.
5574 
5575    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5576 
5577    Input Parameters:
5578 +  mat - the matrix
5579 -  option - the option, this only responds to certain options, check the code for which ones
5580 
5581    Output Parameter:
5582 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5583 
5584     Notes:
5585     Can only be called after MatSetSizes() and MatSetType() have been set.
5586 
5587    Level: intermediate
5588 
5589 .seealso:  MatOption, MatSetOption()
5590 
5591 @*/
5592 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5593 {
5594   PetscFunctionBegin;
5595   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5596   PetscValidType(mat,1);
5597 
5598   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);
5599   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()");
5600 
5601   switch (op) {
5602   case MAT_NO_OFF_PROC_ENTRIES:
5603     *flg = mat->nooffprocentries;
5604     break;
5605   case MAT_NO_OFF_PROC_ZERO_ROWS:
5606     *flg = mat->nooffproczerorows;
5607     break;
5608   case MAT_SYMMETRIC:
5609     *flg = mat->symmetric;
5610     break;
5611   case MAT_HERMITIAN:
5612     *flg = mat->hermitian;
5613     break;
5614   case MAT_STRUCTURALLY_SYMMETRIC:
5615     *flg = mat->structurally_symmetric;
5616     break;
5617   case MAT_SYMMETRY_ETERNAL:
5618     *flg = mat->symmetric_eternal;
5619     break;
5620   case MAT_SPD:
5621     *flg = mat->spd;
5622     break;
5623   default:
5624     break;
5625   }
5626   PetscFunctionReturn(0);
5627 }
5628 
5629 /*@
5630    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5631    this routine retains the old nonzero structure.
5632 
5633    Logically Collective on Mat
5634 
5635    Input Parameters:
5636 .  mat - the matrix
5637 
5638    Level: intermediate
5639 
5640    Notes:
5641     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.
5642    See the Performance chapter of the users manual for information on preallocating matrices.
5643 
5644 .seealso: MatZeroRows()
5645 @*/
5646 PetscErrorCode MatZeroEntries(Mat mat)
5647 {
5648   PetscErrorCode ierr;
5649 
5650   PetscFunctionBegin;
5651   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5652   PetscValidType(mat,1);
5653   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5654   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");
5655   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5656   MatCheckPreallocated(mat,1);
5657 
5658   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5659   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5660   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5661   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5662   PetscFunctionReturn(0);
5663 }
5664 
5665 /*@
5666    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5667    of a set of rows and columns of a matrix.
5668 
5669    Collective on Mat
5670 
5671    Input Parameters:
5672 +  mat - the matrix
5673 .  numRows - the number of rows to remove
5674 .  rows - the global row indices
5675 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5676 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5677 -  b - optional vector of right hand side, that will be adjusted by provided solution
5678 
5679    Notes:
5680    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5681 
5682    The user can set a value in the diagonal entry (or for the AIJ and
5683    row formats can optionally remove the main diagonal entry from the
5684    nonzero structure as well, by passing 0.0 as the final argument).
5685 
5686    For the parallel case, all processes that share the matrix (i.e.,
5687    those in the communicator used for matrix creation) MUST call this
5688    routine, regardless of whether any rows being zeroed are owned by
5689    them.
5690 
5691    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5692    list only rows local to itself).
5693 
5694    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5695 
5696    Level: intermediate
5697 
5698 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5699           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5700 @*/
5701 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5702 {
5703   PetscErrorCode ierr;
5704 
5705   PetscFunctionBegin;
5706   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5707   PetscValidType(mat,1);
5708   if (numRows) PetscValidIntPointer(rows,3);
5709   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5710   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5711   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5712   MatCheckPreallocated(mat,1);
5713 
5714   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5715   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5716   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5717   PetscFunctionReturn(0);
5718 }
5719 
5720 /*@
5721    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5722    of a set of rows and columns of a matrix.
5723 
5724    Collective on Mat
5725 
5726    Input Parameters:
5727 +  mat - the matrix
5728 .  is - the rows to zero
5729 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5730 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5731 -  b - optional vector of right hand side, that will be adjusted by provided solution
5732 
5733    Notes:
5734    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5735 
5736    The user can set a value in the diagonal entry (or for the AIJ and
5737    row formats can optionally remove the main diagonal entry from the
5738    nonzero structure as well, by passing 0.0 as the final argument).
5739 
5740    For the parallel case, all processes that share the matrix (i.e.,
5741    those in the communicator used for matrix creation) MUST call this
5742    routine, regardless of whether any rows being zeroed are owned by
5743    them.
5744 
5745    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5746    list only rows local to itself).
5747 
5748    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5749 
5750    Level: intermediate
5751 
5752 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5753           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5754 @*/
5755 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5756 {
5757   PetscErrorCode ierr;
5758   PetscInt       numRows;
5759   const PetscInt *rows;
5760 
5761   PetscFunctionBegin;
5762   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5763   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5764   PetscValidType(mat,1);
5765   PetscValidType(is,2);
5766   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5767   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5768   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5769   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5770   PetscFunctionReturn(0);
5771 }
5772 
5773 /*@
5774    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5775    of a set of rows of a matrix.
5776 
5777    Collective on Mat
5778 
5779    Input Parameters:
5780 +  mat - the matrix
5781 .  numRows - the number of rows to remove
5782 .  rows - the global row indices
5783 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5784 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5785 -  b - optional vector of right hand side, that will be adjusted by provided solution
5786 
5787    Notes:
5788    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5789    but does not release memory.  For the dense and block diagonal
5790    formats this does not alter the nonzero structure.
5791 
5792    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5793    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5794    merely zeroed.
5795 
5796    The user can set a value in the diagonal entry (or for the AIJ and
5797    row formats can optionally remove the main diagonal entry from the
5798    nonzero structure as well, by passing 0.0 as the final argument).
5799 
5800    For the parallel case, all processes that share the matrix (i.e.,
5801    those in the communicator used for matrix creation) MUST call this
5802    routine, regardless of whether any rows being zeroed are owned by
5803    them.
5804 
5805    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5806    list only rows local to itself).
5807 
5808    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5809    owns that are to be zeroed. This saves a global synchronization in the implementation.
5810 
5811    Level: intermediate
5812 
5813 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5814           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5815 @*/
5816 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5817 {
5818   PetscErrorCode ierr;
5819 
5820   PetscFunctionBegin;
5821   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5822   PetscValidType(mat,1);
5823   if (numRows) PetscValidIntPointer(rows,3);
5824   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5825   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5826   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5827   MatCheckPreallocated(mat,1);
5828 
5829   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5830   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5831   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5832   PetscFunctionReturn(0);
5833 }
5834 
5835 /*@
5836    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5837    of a set of rows of a matrix.
5838 
5839    Collective on Mat
5840 
5841    Input Parameters:
5842 +  mat - the matrix
5843 .  is - index set of rows to remove
5844 .  diag - value put in all diagonals of eliminated rows
5845 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5846 -  b - optional vector of right hand side, that will be adjusted by provided solution
5847 
5848    Notes:
5849    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5850    but does not release memory.  For the dense and block diagonal
5851    formats this does not alter the nonzero structure.
5852 
5853    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5854    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5855    merely zeroed.
5856 
5857    The user can set a value in the diagonal entry (or for the AIJ and
5858    row formats can optionally remove the main diagonal entry from the
5859    nonzero structure as well, by passing 0.0 as the final argument).
5860 
5861    For the parallel case, all processes that share the matrix (i.e.,
5862    those in the communicator used for matrix creation) MUST call this
5863    routine, regardless of whether any rows being zeroed are owned by
5864    them.
5865 
5866    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5867    list only rows local to itself).
5868 
5869    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5870    owns that are to be zeroed. This saves a global synchronization in the implementation.
5871 
5872    Level: intermediate
5873 
5874 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5875           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5876 @*/
5877 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5878 {
5879   PetscInt       numRows;
5880   const PetscInt *rows;
5881   PetscErrorCode ierr;
5882 
5883   PetscFunctionBegin;
5884   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5885   PetscValidType(mat,1);
5886   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5887   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5888   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5889   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5890   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5891   PetscFunctionReturn(0);
5892 }
5893 
5894 /*@
5895    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5896    of a set of rows of a matrix. These rows must be local to the process.
5897 
5898    Collective on Mat
5899 
5900    Input Parameters:
5901 +  mat - the matrix
5902 .  numRows - the number of rows to remove
5903 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5904 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5905 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5906 -  b - optional vector of right hand side, that will be adjusted by provided solution
5907 
5908    Notes:
5909    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5910    but does not release memory.  For the dense and block diagonal
5911    formats this does not alter the nonzero structure.
5912 
5913    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5914    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5915    merely zeroed.
5916 
5917    The user can set a value in the diagonal entry (or for the AIJ and
5918    row formats can optionally remove the main diagonal entry from the
5919    nonzero structure as well, by passing 0.0 as the final argument).
5920 
5921    For the parallel case, all processes that share the matrix (i.e.,
5922    those in the communicator used for matrix creation) MUST call this
5923    routine, regardless of whether any rows being zeroed are owned by
5924    them.
5925 
5926    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5927    list only rows local to itself).
5928 
5929    The grid coordinates are across the entire grid, not just the local portion
5930 
5931    In Fortran idxm and idxn should be declared as
5932 $     MatStencil idxm(4,m)
5933    and the values inserted using
5934 $    idxm(MatStencil_i,1) = i
5935 $    idxm(MatStencil_j,1) = j
5936 $    idxm(MatStencil_k,1) = k
5937 $    idxm(MatStencil_c,1) = c
5938    etc
5939 
5940    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5941    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5942    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5943    DM_BOUNDARY_PERIODIC boundary type.
5944 
5945    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
5946    a single value per point) you can skip filling those indices.
5947 
5948    Level: intermediate
5949 
5950 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5951           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5952 @*/
5953 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5954 {
5955   PetscInt       dim     = mat->stencil.dim;
5956   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5957   PetscInt       *dims   = mat->stencil.dims+1;
5958   PetscInt       *starts = mat->stencil.starts;
5959   PetscInt       *dxm    = (PetscInt*) rows;
5960   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5961   PetscErrorCode ierr;
5962 
5963   PetscFunctionBegin;
5964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5965   PetscValidType(mat,1);
5966   if (numRows) PetscValidIntPointer(rows,3);
5967 
5968   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5969   for (i = 0; i < numRows; ++i) {
5970     /* Skip unused dimensions (they are ordered k, j, i, c) */
5971     for (j = 0; j < 3-sdim; ++j) dxm++;
5972     /* Local index in X dir */
5973     tmp = *dxm++ - starts[0];
5974     /* Loop over remaining dimensions */
5975     for (j = 0; j < dim-1; ++j) {
5976       /* If nonlocal, set index to be negative */
5977       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5978       /* Update local index */
5979       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5980     }
5981     /* Skip component slot if necessary */
5982     if (mat->stencil.noc) dxm++;
5983     /* Local row number */
5984     if (tmp >= 0) {
5985       jdxm[numNewRows++] = tmp;
5986     }
5987   }
5988   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5989   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5990   PetscFunctionReturn(0);
5991 }
5992 
5993 /*@
5994    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5995    of a set of rows and columns of a matrix.
5996 
5997    Collective on Mat
5998 
5999    Input Parameters:
6000 +  mat - the matrix
6001 .  numRows - the number of rows/columns to remove
6002 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6003 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6004 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6005 -  b - optional vector of right hand side, that will be adjusted by provided solution
6006 
6007    Notes:
6008    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6009    but does not release memory.  For the dense and block diagonal
6010    formats this does not alter the nonzero structure.
6011 
6012    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6013    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6014    merely zeroed.
6015 
6016    The user can set a value in the diagonal entry (or for the AIJ and
6017    row formats can optionally remove the main diagonal entry from the
6018    nonzero structure as well, by passing 0.0 as the final argument).
6019 
6020    For the parallel case, all processes that share the matrix (i.e.,
6021    those in the communicator used for matrix creation) MUST call this
6022    routine, regardless of whether any rows being zeroed are owned by
6023    them.
6024 
6025    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6026    list only rows local to itself, but the row/column numbers are given in local numbering).
6027 
6028    The grid coordinates are across the entire grid, not just the local portion
6029 
6030    In Fortran idxm and idxn should be declared as
6031 $     MatStencil idxm(4,m)
6032    and the values inserted using
6033 $    idxm(MatStencil_i,1) = i
6034 $    idxm(MatStencil_j,1) = j
6035 $    idxm(MatStencil_k,1) = k
6036 $    idxm(MatStencil_c,1) = c
6037    etc
6038 
6039    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6040    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6041    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6042    DM_BOUNDARY_PERIODIC boundary type.
6043 
6044    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
6045    a single value per point) you can skip filling those indices.
6046 
6047    Level: intermediate
6048 
6049 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6050           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6051 @*/
6052 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6053 {
6054   PetscInt       dim     = mat->stencil.dim;
6055   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6056   PetscInt       *dims   = mat->stencil.dims+1;
6057   PetscInt       *starts = mat->stencil.starts;
6058   PetscInt       *dxm    = (PetscInt*) rows;
6059   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6060   PetscErrorCode ierr;
6061 
6062   PetscFunctionBegin;
6063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6064   PetscValidType(mat,1);
6065   if (numRows) PetscValidIntPointer(rows,3);
6066 
6067   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6068   for (i = 0; i < numRows; ++i) {
6069     /* Skip unused dimensions (they are ordered k, j, i, c) */
6070     for (j = 0; j < 3-sdim; ++j) dxm++;
6071     /* Local index in X dir */
6072     tmp = *dxm++ - starts[0];
6073     /* Loop over remaining dimensions */
6074     for (j = 0; j < dim-1; ++j) {
6075       /* If nonlocal, set index to be negative */
6076       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6077       /* Update local index */
6078       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6079     }
6080     /* Skip component slot if necessary */
6081     if (mat->stencil.noc) dxm++;
6082     /* Local row number */
6083     if (tmp >= 0) {
6084       jdxm[numNewRows++] = tmp;
6085     }
6086   }
6087   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6088   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6089   PetscFunctionReturn(0);
6090 }
6091 
6092 /*@C
6093    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6094    of a set of rows of a matrix; using local numbering of rows.
6095 
6096    Collective on Mat
6097 
6098    Input Parameters:
6099 +  mat - the matrix
6100 .  numRows - the number of rows to remove
6101 .  rows - the global row indices
6102 .  diag - value put in all diagonals of eliminated rows
6103 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6104 -  b - optional vector of right hand side, that will be adjusted by provided solution
6105 
6106    Notes:
6107    Before calling MatZeroRowsLocal(), the user must first set the
6108    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6109 
6110    For the AIJ matrix formats this removes the old nonzero structure,
6111    but does not release memory.  For the dense and block diagonal
6112    formats this does not alter the nonzero structure.
6113 
6114    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6115    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6116    merely zeroed.
6117 
6118    The user can set a value in the diagonal entry (or for the AIJ and
6119    row formats can optionally remove the main diagonal entry from the
6120    nonzero structure as well, by passing 0.0 as the final argument).
6121 
6122    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6123    owns that are to be zeroed. This saves a global synchronization in the implementation.
6124 
6125    Level: intermediate
6126 
6127 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6128           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6129 @*/
6130 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6131 {
6132   PetscErrorCode ierr;
6133 
6134   PetscFunctionBegin;
6135   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6136   PetscValidType(mat,1);
6137   if (numRows) PetscValidIntPointer(rows,3);
6138   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6139   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6140   MatCheckPreallocated(mat,1);
6141 
6142   if (mat->ops->zerorowslocal) {
6143     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6144   } else {
6145     IS             is, newis;
6146     const PetscInt *newRows;
6147 
6148     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6149     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6150     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6151     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6152     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6153     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6154     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6155     ierr = ISDestroy(&is);CHKERRQ(ierr);
6156   }
6157   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6158   PetscFunctionReturn(0);
6159 }
6160 
6161 /*@
6162    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6163    of a set of rows of a matrix; using local numbering of rows.
6164 
6165    Collective on Mat
6166 
6167    Input Parameters:
6168 +  mat - the matrix
6169 .  is - index set of rows to remove
6170 .  diag - value put in all diagonals of eliminated rows
6171 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6172 -  b - optional vector of right hand side, that will be adjusted by provided solution
6173 
6174    Notes:
6175    Before calling MatZeroRowsLocalIS(), the user must first set the
6176    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6177 
6178    For the AIJ matrix formats this removes the old nonzero structure,
6179    but does not release memory.  For the dense and block diagonal
6180    formats this does not alter the nonzero structure.
6181 
6182    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6183    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6184    merely zeroed.
6185 
6186    The user can set a value in the diagonal entry (or for the AIJ and
6187    row formats can optionally remove the main diagonal entry from the
6188    nonzero structure as well, by passing 0.0 as the final argument).
6189 
6190    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6191    owns that are to be zeroed. This saves a global synchronization in the implementation.
6192 
6193    Level: intermediate
6194 
6195 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6196           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6197 @*/
6198 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6199 {
6200   PetscErrorCode ierr;
6201   PetscInt       numRows;
6202   const PetscInt *rows;
6203 
6204   PetscFunctionBegin;
6205   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6206   PetscValidType(mat,1);
6207   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6208   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6209   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6210   MatCheckPreallocated(mat,1);
6211 
6212   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6213   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6214   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6215   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6216   PetscFunctionReturn(0);
6217 }
6218 
6219 /*@
6220    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6221    of a set of rows and columns of a matrix; using local numbering of rows.
6222 
6223    Collective on Mat
6224 
6225    Input Parameters:
6226 +  mat - the matrix
6227 .  numRows - the number of rows to remove
6228 .  rows - the global row indices
6229 .  diag - value put in all diagonals of eliminated rows
6230 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6231 -  b - optional vector of right hand side, that will be adjusted by provided solution
6232 
6233    Notes:
6234    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6235    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6236 
6237    The user can set a value in the diagonal entry (or for the AIJ and
6238    row formats can optionally remove the main diagonal entry from the
6239    nonzero structure as well, by passing 0.0 as the final argument).
6240 
6241    Level: intermediate
6242 
6243 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6244           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6245 @*/
6246 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6247 {
6248   PetscErrorCode ierr;
6249   IS             is, newis;
6250   const PetscInt *newRows;
6251 
6252   PetscFunctionBegin;
6253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6254   PetscValidType(mat,1);
6255   if (numRows) PetscValidIntPointer(rows,3);
6256   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6257   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6258   MatCheckPreallocated(mat,1);
6259 
6260   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6261   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6262   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6263   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6264   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6265   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6266   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6267   ierr = ISDestroy(&is);CHKERRQ(ierr);
6268   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6269   PetscFunctionReturn(0);
6270 }
6271 
6272 /*@
6273    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6274    of a set of rows and columns of a matrix; using local numbering of rows.
6275 
6276    Collective on Mat
6277 
6278    Input Parameters:
6279 +  mat - the matrix
6280 .  is - index set of rows to remove
6281 .  diag - value put in all diagonals of eliminated rows
6282 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6283 -  b - optional vector of right hand side, that will be adjusted by provided solution
6284 
6285    Notes:
6286    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6287    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6288 
6289    The user can set a value in the diagonal entry (or for the AIJ and
6290    row formats can optionally remove the main diagonal entry from the
6291    nonzero structure as well, by passing 0.0 as the final argument).
6292 
6293    Level: intermediate
6294 
6295 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6296           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6297 @*/
6298 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6299 {
6300   PetscErrorCode ierr;
6301   PetscInt       numRows;
6302   const PetscInt *rows;
6303 
6304   PetscFunctionBegin;
6305   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6306   PetscValidType(mat,1);
6307   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6308   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6309   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6310   MatCheckPreallocated(mat,1);
6311 
6312   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6313   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6314   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6315   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6316   PetscFunctionReturn(0);
6317 }
6318 
6319 /*@C
6320    MatGetSize - Returns the numbers of rows and columns in a matrix.
6321 
6322    Not Collective
6323 
6324    Input Parameter:
6325 .  mat - the matrix
6326 
6327    Output Parameters:
6328 +  m - the number of global rows
6329 -  n - the number of global columns
6330 
6331    Note: both output parameters can be NULL on input.
6332 
6333    Level: beginner
6334 
6335 .seealso: MatGetLocalSize()
6336 @*/
6337 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6338 {
6339   PetscFunctionBegin;
6340   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6341   if (m) *m = mat->rmap->N;
6342   if (n) *n = mat->cmap->N;
6343   PetscFunctionReturn(0);
6344 }
6345 
6346 /*@C
6347    MatGetLocalSize - Returns the number of rows and columns in a matrix
6348    stored locally.  This information may be implementation dependent, so
6349    use with care.
6350 
6351    Not Collective
6352 
6353    Input Parameters:
6354 .  mat - the matrix
6355 
6356    Output Parameters:
6357 +  m - the number of local rows
6358 -  n - the number of local columns
6359 
6360    Note: both output parameters can be NULL on input.
6361 
6362    Level: beginner
6363 
6364 .seealso: MatGetSize()
6365 @*/
6366 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6367 {
6368   PetscFunctionBegin;
6369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6370   if (m) PetscValidIntPointer(m,2);
6371   if (n) PetscValidIntPointer(n,3);
6372   if (m) *m = mat->rmap->n;
6373   if (n) *n = mat->cmap->n;
6374   PetscFunctionReturn(0);
6375 }
6376 
6377 /*@C
6378    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6379    this processor. (The columns of the "diagonal block")
6380 
6381    Not Collective, unless matrix has not been allocated, then collective on Mat
6382 
6383    Input Parameters:
6384 .  mat - the matrix
6385 
6386    Output Parameters:
6387 +  m - the global index of the first local column
6388 -  n - one more than the global index of the last local column
6389 
6390    Notes:
6391     both output parameters can be NULL on input.
6392 
6393    Level: developer
6394 
6395 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6396 
6397 @*/
6398 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6399 {
6400   PetscFunctionBegin;
6401   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6402   PetscValidType(mat,1);
6403   if (m) PetscValidIntPointer(m,2);
6404   if (n) PetscValidIntPointer(n,3);
6405   MatCheckPreallocated(mat,1);
6406   if (m) *m = mat->cmap->rstart;
6407   if (n) *n = mat->cmap->rend;
6408   PetscFunctionReturn(0);
6409 }
6410 
6411 /*@C
6412    MatGetOwnershipRange - Returns the range of matrix rows owned by
6413    this processor, assuming that the matrix is laid out with the first
6414    n1 rows on the first processor, the next n2 rows on the second, etc.
6415    For certain parallel layouts this range may not be well defined.
6416 
6417    Not Collective
6418 
6419    Input Parameters:
6420 .  mat - the matrix
6421 
6422    Output Parameters:
6423 +  m - the global index of the first local row
6424 -  n - one more than the global index of the last local row
6425 
6426    Note: Both output parameters can be NULL on input.
6427 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6428 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6429 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6430 
6431    Level: beginner
6432 
6433 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6434 
6435 @*/
6436 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6437 {
6438   PetscFunctionBegin;
6439   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6440   PetscValidType(mat,1);
6441   if (m) PetscValidIntPointer(m,2);
6442   if (n) PetscValidIntPointer(n,3);
6443   MatCheckPreallocated(mat,1);
6444   if (m) *m = mat->rmap->rstart;
6445   if (n) *n = mat->rmap->rend;
6446   PetscFunctionReturn(0);
6447 }
6448 
6449 /*@C
6450    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6451    each process
6452 
6453    Not Collective, unless matrix has not been allocated, then collective on Mat
6454 
6455    Input Parameters:
6456 .  mat - the matrix
6457 
6458    Output Parameters:
6459 .  ranges - start of each processors portion plus one more than the total length at the end
6460 
6461    Level: beginner
6462 
6463 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6464 
6465 @*/
6466 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6467 {
6468   PetscErrorCode ierr;
6469 
6470   PetscFunctionBegin;
6471   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6472   PetscValidType(mat,1);
6473   MatCheckPreallocated(mat,1);
6474   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6475   PetscFunctionReturn(0);
6476 }
6477 
6478 /*@C
6479    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6480    this processor. (The columns of the "diagonal blocks" for each process)
6481 
6482    Not Collective, unless matrix has not been allocated, then collective on Mat
6483 
6484    Input Parameters:
6485 .  mat - the matrix
6486 
6487    Output Parameters:
6488 .  ranges - start of each processors portion plus one more then the total length at the end
6489 
6490    Level: beginner
6491 
6492 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6493 
6494 @*/
6495 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6496 {
6497   PetscErrorCode ierr;
6498 
6499   PetscFunctionBegin;
6500   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6501   PetscValidType(mat,1);
6502   MatCheckPreallocated(mat,1);
6503   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6504   PetscFunctionReturn(0);
6505 }
6506 
6507 /*@C
6508    MatGetOwnershipIS - Get row and column ownership as index sets
6509 
6510    Not Collective
6511 
6512    Input Arguments:
6513 .  A - matrix of type Elemental
6514 
6515    Output Arguments:
6516 +  rows - rows in which this process owns elements
6517 -  cols - columns in which this process owns elements
6518 
6519    Level: intermediate
6520 
6521 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6522 @*/
6523 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6524 {
6525   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6526 
6527   PetscFunctionBegin;
6528   MatCheckPreallocated(A,1);
6529   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6530   if (f) {
6531     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6532   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6533     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6534     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6535   }
6536   PetscFunctionReturn(0);
6537 }
6538 
6539 /*@C
6540    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6541    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6542    to complete the factorization.
6543 
6544    Collective on Mat
6545 
6546    Input Parameters:
6547 +  mat - the matrix
6548 .  row - row permutation
6549 .  column - column permutation
6550 -  info - structure containing
6551 $      levels - number of levels of fill.
6552 $      expected fill - as ratio of original fill.
6553 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6554                 missing diagonal entries)
6555 
6556    Output Parameters:
6557 .  fact - new matrix that has been symbolically factored
6558 
6559    Notes:
6560     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6561 
6562    Most users should employ the simplified KSP interface for linear solvers
6563    instead of working directly with matrix algebra routines such as this.
6564    See, e.g., KSPCreate().
6565 
6566    Level: developer
6567 
6568 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6569           MatGetOrdering(), MatFactorInfo
6570 
6571     Note: this uses the definition of level of fill as in Y. Saad, 2003
6572 
6573     Developer Note: fortran interface is not autogenerated as the f90
6574     interface defintion cannot be generated correctly [due to MatFactorInfo]
6575 
6576    References:
6577      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6578 @*/
6579 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6580 {
6581   PetscErrorCode ierr;
6582 
6583   PetscFunctionBegin;
6584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6585   PetscValidType(mat,1);
6586   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6587   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6588   PetscValidPointer(info,4);
6589   PetscValidPointer(fact,5);
6590   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6591   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6592   if (!(fact)->ops->ilufactorsymbolic) {
6593     MatSolverType spackage;
6594     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6595     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6596   }
6597   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6598   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6599   MatCheckPreallocated(mat,2);
6600 
6601   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6602   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6603   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6604   PetscFunctionReturn(0);
6605 }
6606 
6607 /*@C
6608    MatICCFactorSymbolic - Performs symbolic incomplete
6609    Cholesky factorization for a symmetric matrix.  Use
6610    MatCholeskyFactorNumeric() to complete the factorization.
6611 
6612    Collective on Mat
6613 
6614    Input Parameters:
6615 +  mat - the matrix
6616 .  perm - row and column permutation
6617 -  info - structure containing
6618 $      levels - number of levels of fill.
6619 $      expected fill - as ratio of original fill.
6620 
6621    Output Parameter:
6622 .  fact - the factored matrix
6623 
6624    Notes:
6625    Most users should employ the KSP interface for linear solvers
6626    instead of working directly with matrix algebra routines such as this.
6627    See, e.g., KSPCreate().
6628 
6629    Level: developer
6630 
6631 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6632 
6633     Note: this uses the definition of level of fill as in Y. Saad, 2003
6634 
6635     Developer Note: fortran interface is not autogenerated as the f90
6636     interface defintion cannot be generated correctly [due to MatFactorInfo]
6637 
6638    References:
6639      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6640 @*/
6641 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6642 {
6643   PetscErrorCode ierr;
6644 
6645   PetscFunctionBegin;
6646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6647   PetscValidType(mat,1);
6648   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6649   PetscValidPointer(info,3);
6650   PetscValidPointer(fact,4);
6651   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6652   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6653   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6654   if (!(fact)->ops->iccfactorsymbolic) {
6655     MatSolverType spackage;
6656     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6657     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6658   }
6659   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6660   MatCheckPreallocated(mat,2);
6661 
6662   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6663   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6664   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6665   PetscFunctionReturn(0);
6666 }
6667 
6668 /*@C
6669    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6670    points to an array of valid matrices, they may be reused to store the new
6671    submatrices.
6672 
6673    Collective on Mat
6674 
6675    Input Parameters:
6676 +  mat - the matrix
6677 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6678 .  irow, icol - index sets of rows and columns to extract
6679 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6680 
6681    Output Parameter:
6682 .  submat - the array of submatrices
6683 
6684    Notes:
6685    MatCreateSubMatrices() can extract ONLY sequential submatrices
6686    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6687    to extract a parallel submatrix.
6688 
6689    Some matrix types place restrictions on the row and column
6690    indices, such as that they be sorted or that they be equal to each other.
6691 
6692    The index sets may not have duplicate entries.
6693 
6694    When extracting submatrices from a parallel matrix, each processor can
6695    form a different submatrix by setting the rows and columns of its
6696    individual index sets according to the local submatrix desired.
6697 
6698    When finished using the submatrices, the user should destroy
6699    them with MatDestroySubMatrices().
6700 
6701    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6702    original matrix has not changed from that last call to MatCreateSubMatrices().
6703 
6704    This routine creates the matrices in submat; you should NOT create them before
6705    calling it. It also allocates the array of matrix pointers submat.
6706 
6707    For BAIJ matrices the index sets must respect the block structure, that is if they
6708    request one row/column in a block, they must request all rows/columns that are in
6709    that block. For example, if the block size is 2 you cannot request just row 0 and
6710    column 0.
6711 
6712    Fortran Note:
6713    The Fortran interface is slightly different from that given below; it
6714    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6715 
6716    Level: advanced
6717 
6718 
6719 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6720 @*/
6721 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6722 {
6723   PetscErrorCode ierr;
6724   PetscInt       i;
6725   PetscBool      eq;
6726 
6727   PetscFunctionBegin;
6728   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6729   PetscValidType(mat,1);
6730   if (n) {
6731     PetscValidPointer(irow,3);
6732     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6733     PetscValidPointer(icol,4);
6734     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6735   }
6736   PetscValidPointer(submat,6);
6737   if (n && scall == MAT_REUSE_MATRIX) {
6738     PetscValidPointer(*submat,6);
6739     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6740   }
6741   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6742   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6743   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6744   MatCheckPreallocated(mat,1);
6745 
6746   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6747   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6748   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6749   for (i=0; i<n; i++) {
6750     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6751     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6752     if (eq) {
6753       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6754     }
6755   }
6756   PetscFunctionReturn(0);
6757 }
6758 
6759 /*@C
6760    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6761 
6762    Collective on Mat
6763 
6764    Input Parameters:
6765 +  mat - the matrix
6766 .  n   - the number of submatrixes to be extracted
6767 .  irow, icol - index sets of rows and columns to extract
6768 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6769 
6770    Output Parameter:
6771 .  submat - the array of submatrices
6772 
6773    Level: advanced
6774 
6775 
6776 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6777 @*/
6778 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6779 {
6780   PetscErrorCode ierr;
6781   PetscInt       i;
6782   PetscBool      eq;
6783 
6784   PetscFunctionBegin;
6785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6786   PetscValidType(mat,1);
6787   if (n) {
6788     PetscValidPointer(irow,3);
6789     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6790     PetscValidPointer(icol,4);
6791     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6792   }
6793   PetscValidPointer(submat,6);
6794   if (n && scall == MAT_REUSE_MATRIX) {
6795     PetscValidPointer(*submat,6);
6796     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6797   }
6798   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6799   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6800   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6801   MatCheckPreallocated(mat,1);
6802 
6803   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6804   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6805   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6806   for (i=0; i<n; i++) {
6807     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6808     if (eq) {
6809       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6810     }
6811   }
6812   PetscFunctionReturn(0);
6813 }
6814 
6815 /*@C
6816    MatDestroyMatrices - Destroys an array of matrices.
6817 
6818    Collective on Mat
6819 
6820    Input Parameters:
6821 +  n - the number of local matrices
6822 -  mat - the matrices (note that this is a pointer to the array of matrices)
6823 
6824    Level: advanced
6825 
6826     Notes:
6827     Frees not only the matrices, but also the array that contains the matrices
6828            In Fortran will not free the array.
6829 
6830 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6831 @*/
6832 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6833 {
6834   PetscErrorCode ierr;
6835   PetscInt       i;
6836 
6837   PetscFunctionBegin;
6838   if (!*mat) PetscFunctionReturn(0);
6839   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6840   PetscValidPointer(mat,2);
6841 
6842   for (i=0; i<n; i++) {
6843     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6844   }
6845 
6846   /* memory is allocated even if n = 0 */
6847   ierr = PetscFree(*mat);CHKERRQ(ierr);
6848   PetscFunctionReturn(0);
6849 }
6850 
6851 /*@C
6852    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6853 
6854    Collective on Mat
6855 
6856    Input Parameters:
6857 +  n - the number of local matrices
6858 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6859                        sequence of MatCreateSubMatrices())
6860 
6861    Level: advanced
6862 
6863     Notes:
6864     Frees not only the matrices, but also the array that contains the matrices
6865            In Fortran will not free the array.
6866 
6867 .seealso: MatCreateSubMatrices()
6868 @*/
6869 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6870 {
6871   PetscErrorCode ierr;
6872   Mat            mat0;
6873 
6874   PetscFunctionBegin;
6875   if (!*mat) PetscFunctionReturn(0);
6876   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6877   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6878   PetscValidPointer(mat,2);
6879 
6880   mat0 = (*mat)[0];
6881   if (mat0 && mat0->ops->destroysubmatrices) {
6882     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6883   } else {
6884     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6885   }
6886   PetscFunctionReturn(0);
6887 }
6888 
6889 /*@C
6890    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6891 
6892    Collective on Mat
6893 
6894    Input Parameters:
6895 .  mat - the matrix
6896 
6897    Output Parameter:
6898 .  matstruct - the sequential matrix with the nonzero structure of mat
6899 
6900   Level: intermediate
6901 
6902 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6903 @*/
6904 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6905 {
6906   PetscErrorCode ierr;
6907 
6908   PetscFunctionBegin;
6909   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6910   PetscValidPointer(matstruct,2);
6911 
6912   PetscValidType(mat,1);
6913   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6914   MatCheckPreallocated(mat,1);
6915 
6916   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6917   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6918   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6919   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6920   PetscFunctionReturn(0);
6921 }
6922 
6923 /*@C
6924    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6925 
6926    Collective on Mat
6927 
6928    Input Parameters:
6929 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6930                        sequence of MatGetSequentialNonzeroStructure())
6931 
6932    Level: advanced
6933 
6934     Notes:
6935     Frees not only the matrices, but also the array that contains the matrices
6936 
6937 .seealso: MatGetSeqNonzeroStructure()
6938 @*/
6939 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6940 {
6941   PetscErrorCode ierr;
6942 
6943   PetscFunctionBegin;
6944   PetscValidPointer(mat,1);
6945   ierr = MatDestroy(mat);CHKERRQ(ierr);
6946   PetscFunctionReturn(0);
6947 }
6948 
6949 /*@
6950    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6951    replaces the index sets by larger ones that represent submatrices with
6952    additional overlap.
6953 
6954    Collective on Mat
6955 
6956    Input Parameters:
6957 +  mat - the matrix
6958 .  n   - the number of index sets
6959 .  is  - the array of index sets (these index sets will changed during the call)
6960 -  ov  - the additional overlap requested
6961 
6962    Options Database:
6963 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6964 
6965    Level: developer
6966 
6967 
6968 .seealso: MatCreateSubMatrices()
6969 @*/
6970 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6971 {
6972   PetscErrorCode ierr;
6973 
6974   PetscFunctionBegin;
6975   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6976   PetscValidType(mat,1);
6977   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6978   if (n) {
6979     PetscValidPointer(is,3);
6980     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6981   }
6982   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6983   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6984   MatCheckPreallocated(mat,1);
6985 
6986   if (!ov) PetscFunctionReturn(0);
6987   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6988   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6989   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6990   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6991   PetscFunctionReturn(0);
6992 }
6993 
6994 
6995 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6996 
6997 /*@
6998    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6999    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7000    additional overlap.
7001 
7002    Collective on Mat
7003 
7004    Input Parameters:
7005 +  mat - the matrix
7006 .  n   - the number of index sets
7007 .  is  - the array of index sets (these index sets will changed during the call)
7008 -  ov  - the additional overlap requested
7009 
7010    Options Database:
7011 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7012 
7013    Level: developer
7014 
7015 
7016 .seealso: MatCreateSubMatrices()
7017 @*/
7018 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7019 {
7020   PetscInt       i;
7021   PetscErrorCode ierr;
7022 
7023   PetscFunctionBegin;
7024   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7025   PetscValidType(mat,1);
7026   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7027   if (n) {
7028     PetscValidPointer(is,3);
7029     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7030   }
7031   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7032   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7033   MatCheckPreallocated(mat,1);
7034   if (!ov) PetscFunctionReturn(0);
7035   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7036   for(i=0; i<n; i++){
7037 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7038   }
7039   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7040   PetscFunctionReturn(0);
7041 }
7042 
7043 
7044 
7045 
7046 /*@
7047    MatGetBlockSize - Returns the matrix block size.
7048 
7049    Not Collective
7050 
7051    Input Parameter:
7052 .  mat - the matrix
7053 
7054    Output Parameter:
7055 .  bs - block size
7056 
7057    Notes:
7058     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7059 
7060    If the block size has not been set yet this routine returns 1.
7061 
7062    Level: intermediate
7063 
7064 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7065 @*/
7066 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7067 {
7068   PetscFunctionBegin;
7069   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7070   PetscValidIntPointer(bs,2);
7071   *bs = PetscAbs(mat->rmap->bs);
7072   PetscFunctionReturn(0);
7073 }
7074 
7075 /*@
7076    MatGetBlockSizes - Returns the matrix block row and column sizes.
7077 
7078    Not Collective
7079 
7080    Input Parameter:
7081 .  mat - the matrix
7082 
7083    Output Parameter:
7084 +  rbs - row block size
7085 -  cbs - column block size
7086 
7087    Notes:
7088     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7089     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7090 
7091    If a block size has not been set yet this routine returns 1.
7092 
7093    Level: intermediate
7094 
7095 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7096 @*/
7097 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7098 {
7099   PetscFunctionBegin;
7100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7101   if (rbs) PetscValidIntPointer(rbs,2);
7102   if (cbs) PetscValidIntPointer(cbs,3);
7103   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7104   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7105   PetscFunctionReturn(0);
7106 }
7107 
7108 /*@
7109    MatSetBlockSize - Sets the matrix block size.
7110 
7111    Logically Collective on Mat
7112 
7113    Input Parameters:
7114 +  mat - the matrix
7115 -  bs - block size
7116 
7117    Notes:
7118     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7119     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7120 
7121     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7122     is compatible with the matrix local sizes.
7123 
7124    Level: intermediate
7125 
7126 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7127 @*/
7128 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7129 {
7130   PetscErrorCode ierr;
7131 
7132   PetscFunctionBegin;
7133   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7134   PetscValidLogicalCollectiveInt(mat,bs,2);
7135   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7136   PetscFunctionReturn(0);
7137 }
7138 
7139 /*@
7140    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7141 
7142    Logically Collective on Mat
7143 
7144    Input Parameters:
7145 +  mat - the matrix
7146 .  nblocks - the number of blocks on this process
7147 -  bsizes - the block sizes
7148 
7149    Notes:
7150     Currently used by PCVPBJACOBI for SeqAIJ matrices
7151 
7152    Level: intermediate
7153 
7154 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7155 @*/
7156 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7157 {
7158   PetscErrorCode ierr;
7159   PetscInt       i,ncnt = 0, nlocal;
7160 
7161   PetscFunctionBegin;
7162   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7163   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7164   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7165   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7166   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);
7167   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7168   mat->nblocks = nblocks;
7169   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7170   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7171   PetscFunctionReturn(0);
7172 }
7173 
7174 /*@C
7175    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7176 
7177    Logically Collective on Mat
7178 
7179    Input Parameters:
7180 .  mat - the matrix
7181 
7182    Output Parameters:
7183 +  nblocks - the number of blocks on this process
7184 -  bsizes - the block sizes
7185 
7186    Notes: Currently not supported from Fortran
7187 
7188    Level: intermediate
7189 
7190 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7191 @*/
7192 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7193 {
7194   PetscFunctionBegin;
7195   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7196   *nblocks = mat->nblocks;
7197   *bsizes  = mat->bsizes;
7198   PetscFunctionReturn(0);
7199 }
7200 
7201 /*@
7202    MatSetBlockSizes - Sets the matrix block row and column sizes.
7203 
7204    Logically Collective on Mat
7205 
7206    Input Parameters:
7207 +  mat - the matrix
7208 .  rbs - row block size
7209 -  cbs - column block size
7210 
7211    Notes:
7212     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7213     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7214     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7215 
7216     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7217     are compatible with the matrix local sizes.
7218 
7219     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7220 
7221    Level: intermediate
7222 
7223 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7224 @*/
7225 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7226 {
7227   PetscErrorCode ierr;
7228 
7229   PetscFunctionBegin;
7230   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7231   PetscValidLogicalCollectiveInt(mat,rbs,2);
7232   PetscValidLogicalCollectiveInt(mat,cbs,3);
7233   if (mat->ops->setblocksizes) {
7234     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7235   }
7236   if (mat->rmap->refcnt) {
7237     ISLocalToGlobalMapping l2g = NULL;
7238     PetscLayout            nmap = NULL;
7239 
7240     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7241     if (mat->rmap->mapping) {
7242       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7243     }
7244     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7245     mat->rmap = nmap;
7246     mat->rmap->mapping = l2g;
7247   }
7248   if (mat->cmap->refcnt) {
7249     ISLocalToGlobalMapping l2g = NULL;
7250     PetscLayout            nmap = NULL;
7251 
7252     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7253     if (mat->cmap->mapping) {
7254       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7255     }
7256     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7257     mat->cmap = nmap;
7258     mat->cmap->mapping = l2g;
7259   }
7260   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7261   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7262   PetscFunctionReturn(0);
7263 }
7264 
7265 /*@
7266    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7267 
7268    Logically Collective on Mat
7269 
7270    Input Parameters:
7271 +  mat - the matrix
7272 .  fromRow - matrix from which to copy row block size
7273 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7274 
7275    Level: developer
7276 
7277 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7278 @*/
7279 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7280 {
7281   PetscErrorCode ierr;
7282 
7283   PetscFunctionBegin;
7284   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7285   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7286   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7287   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7288   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7289   PetscFunctionReturn(0);
7290 }
7291 
7292 /*@
7293    MatResidual - Default routine to calculate the residual.
7294 
7295    Collective on Mat
7296 
7297    Input Parameters:
7298 +  mat - the matrix
7299 .  b   - the right-hand-side
7300 -  x   - the approximate solution
7301 
7302    Output Parameter:
7303 .  r - location to store the residual
7304 
7305    Level: developer
7306 
7307 .seealso: PCMGSetResidual()
7308 @*/
7309 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7310 {
7311   PetscErrorCode ierr;
7312 
7313   PetscFunctionBegin;
7314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7315   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7316   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7317   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7318   PetscValidType(mat,1);
7319   MatCheckPreallocated(mat,1);
7320   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7321   if (!mat->ops->residual) {
7322     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7323     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7324   } else {
7325     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7326   }
7327   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7328   PetscFunctionReturn(0);
7329 }
7330 
7331 /*@C
7332     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7333 
7334    Collective on Mat
7335 
7336     Input Parameters:
7337 +   mat - the matrix
7338 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7339 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7340 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7341                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7342                  always used.
7343 
7344     Output Parameters:
7345 +   n - number of rows in the (possibly compressed) matrix
7346 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7347 .   ja - the column indices
7348 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7349            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7350 
7351     Level: developer
7352 
7353     Notes:
7354     You CANNOT change any of the ia[] or ja[] values.
7355 
7356     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7357 
7358     Fortran Notes:
7359     In Fortran use
7360 $
7361 $      PetscInt ia(1), ja(1)
7362 $      PetscOffset iia, jja
7363 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7364 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7365 
7366      or
7367 $
7368 $    PetscInt, pointer :: ia(:),ja(:)
7369 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7370 $    ! Access the ith and jth entries via ia(i) and ja(j)
7371 
7372 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7373 @*/
7374 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7375 {
7376   PetscErrorCode ierr;
7377 
7378   PetscFunctionBegin;
7379   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7380   PetscValidType(mat,1);
7381   PetscValidIntPointer(n,5);
7382   if (ia) PetscValidIntPointer(ia,6);
7383   if (ja) PetscValidIntPointer(ja,7);
7384   PetscValidIntPointer(done,8);
7385   MatCheckPreallocated(mat,1);
7386   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7387   else {
7388     *done = PETSC_TRUE;
7389     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7390     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7391     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7392   }
7393   PetscFunctionReturn(0);
7394 }
7395 
7396 /*@C
7397     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7398 
7399     Collective on Mat
7400 
7401     Input Parameters:
7402 +   mat - the matrix
7403 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7404 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7405                 symmetrized
7406 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7407                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7408                  always used.
7409 .   n - number of columns in the (possibly compressed) matrix
7410 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7411 -   ja - the row indices
7412 
7413     Output Parameters:
7414 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7415 
7416     Level: developer
7417 
7418 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7419 @*/
7420 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7421 {
7422   PetscErrorCode ierr;
7423 
7424   PetscFunctionBegin;
7425   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7426   PetscValidType(mat,1);
7427   PetscValidIntPointer(n,4);
7428   if (ia) PetscValidIntPointer(ia,5);
7429   if (ja) PetscValidIntPointer(ja,6);
7430   PetscValidIntPointer(done,7);
7431   MatCheckPreallocated(mat,1);
7432   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7433   else {
7434     *done = PETSC_TRUE;
7435     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7436   }
7437   PetscFunctionReturn(0);
7438 }
7439 
7440 /*@C
7441     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7442     MatGetRowIJ().
7443 
7444     Collective on Mat
7445 
7446     Input Parameters:
7447 +   mat - the matrix
7448 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7449 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7450                 symmetrized
7451 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7452                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7453                  always used.
7454 .   n - size of (possibly compressed) matrix
7455 .   ia - the row pointers
7456 -   ja - the column indices
7457 
7458     Output Parameters:
7459 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7460 
7461     Note:
7462     This routine zeros out n, ia, and ja. This is to prevent accidental
7463     us of the array after it has been restored. If you pass NULL, it will
7464     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7465 
7466     Level: developer
7467 
7468 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7469 @*/
7470 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7471 {
7472   PetscErrorCode ierr;
7473 
7474   PetscFunctionBegin;
7475   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7476   PetscValidType(mat,1);
7477   if (ia) PetscValidIntPointer(ia,6);
7478   if (ja) PetscValidIntPointer(ja,7);
7479   PetscValidIntPointer(done,8);
7480   MatCheckPreallocated(mat,1);
7481 
7482   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7483   else {
7484     *done = PETSC_TRUE;
7485     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7486     if (n)  *n = 0;
7487     if (ia) *ia = NULL;
7488     if (ja) *ja = NULL;
7489   }
7490   PetscFunctionReturn(0);
7491 }
7492 
7493 /*@C
7494     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7495     MatGetColumnIJ().
7496 
7497     Collective on Mat
7498 
7499     Input Parameters:
7500 +   mat - the matrix
7501 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7502 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7503                 symmetrized
7504 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7505                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7506                  always used.
7507 
7508     Output Parameters:
7509 +   n - size of (possibly compressed) matrix
7510 .   ia - the column pointers
7511 .   ja - the row indices
7512 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7513 
7514     Level: developer
7515 
7516 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7517 @*/
7518 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7519 {
7520   PetscErrorCode ierr;
7521 
7522   PetscFunctionBegin;
7523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7524   PetscValidType(mat,1);
7525   if (ia) PetscValidIntPointer(ia,5);
7526   if (ja) PetscValidIntPointer(ja,6);
7527   PetscValidIntPointer(done,7);
7528   MatCheckPreallocated(mat,1);
7529 
7530   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7531   else {
7532     *done = PETSC_TRUE;
7533     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7534     if (n)  *n = 0;
7535     if (ia) *ia = NULL;
7536     if (ja) *ja = NULL;
7537   }
7538   PetscFunctionReturn(0);
7539 }
7540 
7541 /*@C
7542     MatColoringPatch -Used inside matrix coloring routines that
7543     use MatGetRowIJ() and/or MatGetColumnIJ().
7544 
7545     Collective on Mat
7546 
7547     Input Parameters:
7548 +   mat - the matrix
7549 .   ncolors - max color value
7550 .   n   - number of entries in colorarray
7551 -   colorarray - array indicating color for each column
7552 
7553     Output Parameters:
7554 .   iscoloring - coloring generated using colorarray information
7555 
7556     Level: developer
7557 
7558 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7559 
7560 @*/
7561 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7562 {
7563   PetscErrorCode ierr;
7564 
7565   PetscFunctionBegin;
7566   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7567   PetscValidType(mat,1);
7568   PetscValidIntPointer(colorarray,4);
7569   PetscValidPointer(iscoloring,5);
7570   MatCheckPreallocated(mat,1);
7571 
7572   if (!mat->ops->coloringpatch) {
7573     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7574   } else {
7575     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7576   }
7577   PetscFunctionReturn(0);
7578 }
7579 
7580 
7581 /*@
7582    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7583 
7584    Logically Collective on Mat
7585 
7586    Input Parameter:
7587 .  mat - the factored matrix to be reset
7588 
7589    Notes:
7590    This routine should be used only with factored matrices formed by in-place
7591    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7592    format).  This option can save memory, for example, when solving nonlinear
7593    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7594    ILU(0) preconditioner.
7595 
7596    Note that one can specify in-place ILU(0) factorization by calling
7597 .vb
7598      PCType(pc,PCILU);
7599      PCFactorSeUseInPlace(pc);
7600 .ve
7601    or by using the options -pc_type ilu -pc_factor_in_place
7602 
7603    In-place factorization ILU(0) can also be used as a local
7604    solver for the blocks within the block Jacobi or additive Schwarz
7605    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7606    for details on setting local solver options.
7607 
7608    Most users should employ the simplified KSP interface for linear solvers
7609    instead of working directly with matrix algebra routines such as this.
7610    See, e.g., KSPCreate().
7611 
7612    Level: developer
7613 
7614 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7615 
7616 @*/
7617 PetscErrorCode MatSetUnfactored(Mat mat)
7618 {
7619   PetscErrorCode ierr;
7620 
7621   PetscFunctionBegin;
7622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7623   PetscValidType(mat,1);
7624   MatCheckPreallocated(mat,1);
7625   mat->factortype = MAT_FACTOR_NONE;
7626   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7627   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7628   PetscFunctionReturn(0);
7629 }
7630 
7631 /*MC
7632     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7633 
7634     Synopsis:
7635     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7636 
7637     Not collective
7638 
7639     Input Parameter:
7640 .   x - matrix
7641 
7642     Output Parameters:
7643 +   xx_v - the Fortran90 pointer to the array
7644 -   ierr - error code
7645 
7646     Example of Usage:
7647 .vb
7648       PetscScalar, pointer xx_v(:,:)
7649       ....
7650       call MatDenseGetArrayF90(x,xx_v,ierr)
7651       a = xx_v(3)
7652       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7653 .ve
7654 
7655     Level: advanced
7656 
7657 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7658 
7659 M*/
7660 
7661 /*MC
7662     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7663     accessed with MatDenseGetArrayF90().
7664 
7665     Synopsis:
7666     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7667 
7668     Not collective
7669 
7670     Input Parameters:
7671 +   x - matrix
7672 -   xx_v - the Fortran90 pointer to the array
7673 
7674     Output Parameter:
7675 .   ierr - error code
7676 
7677     Example of Usage:
7678 .vb
7679        PetscScalar, pointer xx_v(:,:)
7680        ....
7681        call MatDenseGetArrayF90(x,xx_v,ierr)
7682        a = xx_v(3)
7683        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7684 .ve
7685 
7686     Level: advanced
7687 
7688 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7689 
7690 M*/
7691 
7692 
7693 /*MC
7694     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7695 
7696     Synopsis:
7697     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7698 
7699     Not collective
7700 
7701     Input Parameter:
7702 .   x - matrix
7703 
7704     Output Parameters:
7705 +   xx_v - the Fortran90 pointer to the array
7706 -   ierr - error code
7707 
7708     Example of Usage:
7709 .vb
7710       PetscScalar, pointer xx_v(:)
7711       ....
7712       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7713       a = xx_v(3)
7714       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7715 .ve
7716 
7717     Level: advanced
7718 
7719 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7720 
7721 M*/
7722 
7723 /*MC
7724     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7725     accessed with MatSeqAIJGetArrayF90().
7726 
7727     Synopsis:
7728     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7729 
7730     Not collective
7731 
7732     Input Parameters:
7733 +   x - matrix
7734 -   xx_v - the Fortran90 pointer to the array
7735 
7736     Output Parameter:
7737 .   ierr - error code
7738 
7739     Example of Usage:
7740 .vb
7741        PetscScalar, pointer xx_v(:)
7742        ....
7743        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7744        a = xx_v(3)
7745        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7746 .ve
7747 
7748     Level: advanced
7749 
7750 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7751 
7752 M*/
7753 
7754 
7755 /*@
7756     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7757                       as the original matrix.
7758 
7759     Collective on Mat
7760 
7761     Input Parameters:
7762 +   mat - the original matrix
7763 .   isrow - parallel IS containing the rows this processor should obtain
7764 .   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.
7765 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7766 
7767     Output Parameter:
7768 .   newmat - the new submatrix, of the same type as the old
7769 
7770     Level: advanced
7771 
7772     Notes:
7773     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7774 
7775     Some matrix types place restrictions on the row and column indices, such
7776     as that they be sorted or that they be equal to each other.
7777 
7778     The index sets may not have duplicate entries.
7779 
7780       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7781    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7782    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7783    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7784    you are finished using it.
7785 
7786     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7787     the input matrix.
7788 
7789     If iscol is NULL then all columns are obtained (not supported in Fortran).
7790 
7791    Example usage:
7792    Consider the following 8x8 matrix with 34 non-zero values, that is
7793    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7794    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7795    as follows:
7796 
7797 .vb
7798             1  2  0  |  0  3  0  |  0  4
7799     Proc0   0  5  6  |  7  0  0  |  8  0
7800             9  0 10  | 11  0  0  | 12  0
7801     -------------------------------------
7802            13  0 14  | 15 16 17  |  0  0
7803     Proc1   0 18  0  | 19 20 21  |  0  0
7804             0  0  0  | 22 23  0  | 24  0
7805     -------------------------------------
7806     Proc2  25 26 27  |  0  0 28  | 29  0
7807            30  0  0  | 31 32 33  |  0 34
7808 .ve
7809 
7810     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7811 
7812 .vb
7813             2  0  |  0  3  0  |  0
7814     Proc0   5  6  |  7  0  0  |  8
7815     -------------------------------
7816     Proc1  18  0  | 19 20 21  |  0
7817     -------------------------------
7818     Proc2  26 27  |  0  0 28  | 29
7819             0  0  | 31 32 33  |  0
7820 .ve
7821 
7822 
7823 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
7824 @*/
7825 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7826 {
7827   PetscErrorCode ierr;
7828   PetscMPIInt    size;
7829   Mat            *local;
7830   IS             iscoltmp;
7831   PetscBool      flg;
7832 
7833   PetscFunctionBegin;
7834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7835   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7836   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7837   PetscValidPointer(newmat,5);
7838   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7839   PetscValidType(mat,1);
7840   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7841   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7842 
7843   MatCheckPreallocated(mat,1);
7844   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7845 
7846   if (!iscol || isrow == iscol) {
7847     PetscBool   stride;
7848     PetscMPIInt grabentirematrix = 0,grab;
7849     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7850     if (stride) {
7851       PetscInt first,step,n,rstart,rend;
7852       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7853       if (step == 1) {
7854         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7855         if (rstart == first) {
7856           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7857           if (n == rend-rstart) {
7858             grabentirematrix = 1;
7859           }
7860         }
7861       }
7862     }
7863     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7864     if (grab) {
7865       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7866       if (cll == MAT_INITIAL_MATRIX) {
7867         *newmat = mat;
7868         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7869       }
7870       PetscFunctionReturn(0);
7871     }
7872   }
7873 
7874   if (!iscol) {
7875     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7876   } else {
7877     iscoltmp = iscol;
7878   }
7879 
7880   /* if original matrix is on just one processor then use submatrix generated */
7881   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7882     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7883     goto setproperties;
7884   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7885     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7886     *newmat = *local;
7887     ierr    = PetscFree(local);CHKERRQ(ierr);
7888     goto setproperties;
7889   } else if (!mat->ops->createsubmatrix) {
7890     /* Create a new matrix type that implements the operation using the full matrix */
7891     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7892     switch (cll) {
7893     case MAT_INITIAL_MATRIX:
7894       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7895       break;
7896     case MAT_REUSE_MATRIX:
7897       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7898       break;
7899     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7900     }
7901     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7902     goto setproperties;
7903   }
7904 
7905   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7906   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7907   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7908   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7909 
7910 setproperties:
7911   ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr);
7912   if (flg) {
7913     ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr);
7914   }
7915   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7916   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7917   PetscFunctionReturn(0);
7918 }
7919 
7920 /*@
7921    MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
7922 
7923    Not Collective
7924 
7925    Input Parameters:
7926 +  A - the matrix we wish to propagate options from
7927 -  B - the matrix we wish to propagate options to
7928 
7929    Level: beginner
7930 
7931    Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
7932 
7933 .seealso: MatSetOption()
7934 @*/
7935 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
7936 {
7937   PetscErrorCode ierr;
7938 
7939   PetscFunctionBegin;
7940   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7941   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
7942   if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
7943     ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr);
7944   }
7945   if (A->structurally_symmetric_set) {
7946     ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr);
7947   }
7948   if (A->hermitian_set) {
7949     ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr);
7950   }
7951   if (A->spd_set) {
7952     ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr);
7953   }
7954   if (A->symmetric_set) {
7955     ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr);
7956   }
7957   PetscFunctionReturn(0);
7958 }
7959 
7960 /*@
7961    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7962    used during the assembly process to store values that belong to
7963    other processors.
7964 
7965    Not Collective
7966 
7967    Input Parameters:
7968 +  mat   - the matrix
7969 .  size  - the initial size of the stash.
7970 -  bsize - the initial size of the block-stash(if used).
7971 
7972    Options Database Keys:
7973 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7974 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7975 
7976    Level: intermediate
7977 
7978    Notes:
7979      The block-stash is used for values set with MatSetValuesBlocked() while
7980      the stash is used for values set with MatSetValues()
7981 
7982      Run with the option -info and look for output of the form
7983      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7984      to determine the appropriate value, MM, to use for size and
7985      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7986      to determine the value, BMM to use for bsize
7987 
7988 
7989 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7990 
7991 @*/
7992 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7993 {
7994   PetscErrorCode ierr;
7995 
7996   PetscFunctionBegin;
7997   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7998   PetscValidType(mat,1);
7999   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8000   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8001   PetscFunctionReturn(0);
8002 }
8003 
8004 /*@
8005    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8006      the matrix
8007 
8008    Neighbor-wise Collective on Mat
8009 
8010    Input Parameters:
8011 +  mat   - the matrix
8012 .  x,y - the vectors
8013 -  w - where the result is stored
8014 
8015    Level: intermediate
8016 
8017    Notes:
8018     w may be the same vector as y.
8019 
8020     This allows one to use either the restriction or interpolation (its transpose)
8021     matrix to do the interpolation
8022 
8023 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8024 
8025 @*/
8026 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8027 {
8028   PetscErrorCode ierr;
8029   PetscInt       M,N,Ny;
8030 
8031   PetscFunctionBegin;
8032   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8033   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8034   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8035   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8036   PetscValidType(A,1);
8037   MatCheckPreallocated(A,1);
8038   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8039   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8040   if (M == Ny) {
8041     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8042   } else {
8043     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8044   }
8045   PetscFunctionReturn(0);
8046 }
8047 
8048 /*@
8049    MatInterpolate - y = A*x or A'*x depending on the shape of
8050      the matrix
8051 
8052    Neighbor-wise Collective on Mat
8053 
8054    Input Parameters:
8055 +  mat   - the matrix
8056 -  x,y - the vectors
8057 
8058    Level: intermediate
8059 
8060    Notes:
8061     This allows one to use either the restriction or interpolation (its transpose)
8062     matrix to do the interpolation
8063 
8064 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8065 
8066 @*/
8067 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8068 {
8069   PetscErrorCode ierr;
8070   PetscInt       M,N,Ny;
8071 
8072   PetscFunctionBegin;
8073   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8074   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8075   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8076   PetscValidType(A,1);
8077   MatCheckPreallocated(A,1);
8078   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8079   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8080   if (M == Ny) {
8081     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8082   } else {
8083     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8084   }
8085   PetscFunctionReturn(0);
8086 }
8087 
8088 /*@
8089    MatRestrict - y = A*x or A'*x
8090 
8091    Neighbor-wise Collective on Mat
8092 
8093    Input Parameters:
8094 +  mat   - the matrix
8095 -  x,y - the vectors
8096 
8097    Level: intermediate
8098 
8099    Notes:
8100     This allows one to use either the restriction or interpolation (its transpose)
8101     matrix to do the restriction
8102 
8103 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8104 
8105 @*/
8106 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8107 {
8108   PetscErrorCode ierr;
8109   PetscInt       M,N,Ny;
8110 
8111   PetscFunctionBegin;
8112   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8113   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8114   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8115   PetscValidType(A,1);
8116   MatCheckPreallocated(A,1);
8117 
8118   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8119   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8120   if (M == Ny) {
8121     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8122   } else {
8123     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8124   }
8125   PetscFunctionReturn(0);
8126 }
8127 
8128 /*@
8129    MatGetNullSpace - retrieves the null space of a matrix.
8130 
8131    Logically Collective on Mat
8132 
8133    Input Parameters:
8134 +  mat - the matrix
8135 -  nullsp - the null space object
8136 
8137    Level: developer
8138 
8139 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8140 @*/
8141 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8142 {
8143   PetscFunctionBegin;
8144   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8145   PetscValidPointer(nullsp,2);
8146   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8147   PetscFunctionReturn(0);
8148 }
8149 
8150 /*@
8151    MatSetNullSpace - attaches a null space to a matrix.
8152 
8153    Logically Collective on Mat
8154 
8155    Input Parameters:
8156 +  mat - the matrix
8157 -  nullsp - the null space object
8158 
8159    Level: advanced
8160 
8161    Notes:
8162       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8163 
8164       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8165       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8166 
8167       You can remove the null space by calling this routine with an nullsp of NULL
8168 
8169 
8170       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8171    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).
8172    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
8173    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
8174    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).
8175 
8176       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8177 
8178     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
8179     routine also automatically calls MatSetTransposeNullSpace().
8180 
8181 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8182 @*/
8183 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8184 {
8185   PetscErrorCode ierr;
8186 
8187   PetscFunctionBegin;
8188   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8189   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8190   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8191   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8192   mat->nullsp = nullsp;
8193   if (mat->symmetric_set && mat->symmetric) {
8194     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8195   }
8196   PetscFunctionReturn(0);
8197 }
8198 
8199 /*@
8200    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8201 
8202    Logically Collective on Mat
8203 
8204    Input Parameters:
8205 +  mat - the matrix
8206 -  nullsp - the null space object
8207 
8208    Level: developer
8209 
8210 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8211 @*/
8212 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8213 {
8214   PetscFunctionBegin;
8215   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8216   PetscValidType(mat,1);
8217   PetscValidPointer(nullsp,2);
8218   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8219   PetscFunctionReturn(0);
8220 }
8221 
8222 /*@
8223    MatSetTransposeNullSpace - attaches a null space to a matrix.
8224 
8225    Logically Collective on Mat
8226 
8227    Input Parameters:
8228 +  mat - the matrix
8229 -  nullsp - the null space object
8230 
8231    Level: advanced
8232 
8233    Notes:
8234       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.
8235       You must also call MatSetNullSpace()
8236 
8237 
8238       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8239    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).
8240    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
8241    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
8242    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).
8243 
8244       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8245 
8246 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8247 @*/
8248 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8249 {
8250   PetscErrorCode ierr;
8251 
8252   PetscFunctionBegin;
8253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8254   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8255   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8256   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8257   mat->transnullsp = nullsp;
8258   PetscFunctionReturn(0);
8259 }
8260 
8261 /*@
8262    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8263         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8264 
8265    Logically Collective on Mat
8266 
8267    Input Parameters:
8268 +  mat - the matrix
8269 -  nullsp - the null space object
8270 
8271    Level: advanced
8272 
8273    Notes:
8274       Overwrites any previous near null space that may have been attached
8275 
8276       You can remove the null space by calling this routine with an nullsp of NULL
8277 
8278 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8279 @*/
8280 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8281 {
8282   PetscErrorCode ierr;
8283 
8284   PetscFunctionBegin;
8285   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8286   PetscValidType(mat,1);
8287   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8288   MatCheckPreallocated(mat,1);
8289   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8290   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8291   mat->nearnullsp = nullsp;
8292   PetscFunctionReturn(0);
8293 }
8294 
8295 /*@
8296    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8297 
8298    Not Collective
8299 
8300    Input Parameter:
8301 .  mat - the matrix
8302 
8303    Output Parameter:
8304 .  nullsp - the null space object, NULL if not set
8305 
8306    Level: developer
8307 
8308 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8309 @*/
8310 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8311 {
8312   PetscFunctionBegin;
8313   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8314   PetscValidType(mat,1);
8315   PetscValidPointer(nullsp,2);
8316   MatCheckPreallocated(mat,1);
8317   *nullsp = mat->nearnullsp;
8318   PetscFunctionReturn(0);
8319 }
8320 
8321 /*@C
8322    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8323 
8324    Collective on Mat
8325 
8326    Input Parameters:
8327 +  mat - the matrix
8328 .  row - row/column permutation
8329 .  fill - expected fill factor >= 1.0
8330 -  level - level of fill, for ICC(k)
8331 
8332    Notes:
8333    Probably really in-place only when level of fill is zero, otherwise allocates
8334    new space to store factored matrix and deletes previous memory.
8335 
8336    Most users should employ the simplified KSP interface for linear solvers
8337    instead of working directly with matrix algebra routines such as this.
8338    See, e.g., KSPCreate().
8339 
8340    Level: developer
8341 
8342 
8343 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8344 
8345     Developer Note: fortran interface is not autogenerated as the f90
8346     interface defintion cannot be generated correctly [due to MatFactorInfo]
8347 
8348 @*/
8349 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8350 {
8351   PetscErrorCode ierr;
8352 
8353   PetscFunctionBegin;
8354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8355   PetscValidType(mat,1);
8356   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8357   PetscValidPointer(info,3);
8358   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8359   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8360   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8361   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8362   MatCheckPreallocated(mat,1);
8363   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8364   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8365   PetscFunctionReturn(0);
8366 }
8367 
8368 /*@
8369    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8370          ghosted ones.
8371 
8372    Not Collective
8373 
8374    Input Parameters:
8375 +  mat - the matrix
8376 -  diag = the diagonal values, including ghost ones
8377 
8378    Level: developer
8379 
8380    Notes:
8381     Works only for MPIAIJ and MPIBAIJ matrices
8382 
8383 .seealso: MatDiagonalScale()
8384 @*/
8385 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8386 {
8387   PetscErrorCode ierr;
8388   PetscMPIInt    size;
8389 
8390   PetscFunctionBegin;
8391   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8392   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8393   PetscValidType(mat,1);
8394 
8395   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8396   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8397   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8398   if (size == 1) {
8399     PetscInt n,m;
8400     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8401     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8402     if (m == n) {
8403       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8404     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8405   } else {
8406     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8407   }
8408   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8409   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8410   PetscFunctionReturn(0);
8411 }
8412 
8413 /*@
8414    MatGetInertia - Gets the inertia from a factored matrix
8415 
8416    Collective on Mat
8417 
8418    Input Parameter:
8419 .  mat - the matrix
8420 
8421    Output Parameters:
8422 +   nneg - number of negative eigenvalues
8423 .   nzero - number of zero eigenvalues
8424 -   npos - number of positive eigenvalues
8425 
8426    Level: advanced
8427 
8428    Notes:
8429     Matrix must have been factored by MatCholeskyFactor()
8430 
8431 
8432 @*/
8433 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8434 {
8435   PetscErrorCode ierr;
8436 
8437   PetscFunctionBegin;
8438   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8439   PetscValidType(mat,1);
8440   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8441   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8442   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8443   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8444   PetscFunctionReturn(0);
8445 }
8446 
8447 /* ----------------------------------------------------------------*/
8448 /*@C
8449    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8450 
8451    Neighbor-wise Collective on Mats
8452 
8453    Input Parameters:
8454 +  mat - the factored matrix
8455 -  b - the right-hand-side vectors
8456 
8457    Output Parameter:
8458 .  x - the result vectors
8459 
8460    Notes:
8461    The vectors b and x cannot be the same.  I.e., one cannot
8462    call MatSolves(A,x,x).
8463 
8464    Notes:
8465    Most users should employ the simplified KSP interface for linear solvers
8466    instead of working directly with matrix algebra routines such as this.
8467    See, e.g., KSPCreate().
8468 
8469    Level: developer
8470 
8471 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8472 @*/
8473 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8474 {
8475   PetscErrorCode ierr;
8476 
8477   PetscFunctionBegin;
8478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8479   PetscValidType(mat,1);
8480   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8481   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8482   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8483 
8484   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8485   MatCheckPreallocated(mat,1);
8486   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8487   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8488   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8489   PetscFunctionReturn(0);
8490 }
8491 
8492 /*@
8493    MatIsSymmetric - Test whether a matrix is symmetric
8494 
8495    Collective on Mat
8496 
8497    Input Parameter:
8498 +  A - the matrix to test
8499 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8500 
8501    Output Parameters:
8502 .  flg - the result
8503 
8504    Notes:
8505     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8506 
8507    Level: intermediate
8508 
8509 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8510 @*/
8511 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8512 {
8513   PetscErrorCode ierr;
8514 
8515   PetscFunctionBegin;
8516   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8517   PetscValidBoolPointer(flg,2);
8518 
8519   if (!A->symmetric_set) {
8520     if (!A->ops->issymmetric) {
8521       MatType mattype;
8522       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8523       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8524     }
8525     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8526     if (!tol) {
8527       ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr);
8528     }
8529   } else if (A->symmetric) {
8530     *flg = PETSC_TRUE;
8531   } else if (!tol) {
8532     *flg = PETSC_FALSE;
8533   } else {
8534     if (!A->ops->issymmetric) {
8535       MatType mattype;
8536       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8537       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8538     }
8539     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8540   }
8541   PetscFunctionReturn(0);
8542 }
8543 
8544 /*@
8545    MatIsHermitian - Test whether a matrix is Hermitian
8546 
8547    Collective on Mat
8548 
8549    Input Parameter:
8550 +  A - the matrix to test
8551 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8552 
8553    Output Parameters:
8554 .  flg - the result
8555 
8556    Level: intermediate
8557 
8558 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8559           MatIsSymmetricKnown(), MatIsSymmetric()
8560 @*/
8561 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8562 {
8563   PetscErrorCode ierr;
8564 
8565   PetscFunctionBegin;
8566   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8567   PetscValidBoolPointer(flg,2);
8568 
8569   if (!A->hermitian_set) {
8570     if (!A->ops->ishermitian) {
8571       MatType mattype;
8572       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8573       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8574     }
8575     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8576     if (!tol) {
8577       ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr);
8578     }
8579   } else if (A->hermitian) {
8580     *flg = PETSC_TRUE;
8581   } else if (!tol) {
8582     *flg = PETSC_FALSE;
8583   } else {
8584     if (!A->ops->ishermitian) {
8585       MatType mattype;
8586       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8587       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8588     }
8589     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8590   }
8591   PetscFunctionReturn(0);
8592 }
8593 
8594 /*@
8595    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8596 
8597    Not Collective
8598 
8599    Input Parameter:
8600 .  A - the matrix to check
8601 
8602    Output Parameters:
8603 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8604 -  flg - the result
8605 
8606    Level: advanced
8607 
8608    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8609          if you want it explicitly checked
8610 
8611 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8612 @*/
8613 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8614 {
8615   PetscFunctionBegin;
8616   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8617   PetscValidPointer(set,2);
8618   PetscValidBoolPointer(flg,3);
8619   if (A->symmetric_set) {
8620     *set = PETSC_TRUE;
8621     *flg = A->symmetric;
8622   } else {
8623     *set = PETSC_FALSE;
8624   }
8625   PetscFunctionReturn(0);
8626 }
8627 
8628 /*@
8629    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8630 
8631    Not Collective
8632 
8633    Input Parameter:
8634 .  A - the matrix to check
8635 
8636    Output Parameters:
8637 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8638 -  flg - the result
8639 
8640    Level: advanced
8641 
8642    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8643          if you want it explicitly checked
8644 
8645 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8646 @*/
8647 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8648 {
8649   PetscFunctionBegin;
8650   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8651   PetscValidPointer(set,2);
8652   PetscValidBoolPointer(flg,3);
8653   if (A->hermitian_set) {
8654     *set = PETSC_TRUE;
8655     *flg = A->hermitian;
8656   } else {
8657     *set = PETSC_FALSE;
8658   }
8659   PetscFunctionReturn(0);
8660 }
8661 
8662 /*@
8663    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8664 
8665    Collective on Mat
8666 
8667    Input Parameter:
8668 .  A - the matrix to test
8669 
8670    Output Parameters:
8671 .  flg - the result
8672 
8673    Level: intermediate
8674 
8675 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8676 @*/
8677 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8678 {
8679   PetscErrorCode ierr;
8680 
8681   PetscFunctionBegin;
8682   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8683   PetscValidBoolPointer(flg,2);
8684   if (!A->structurally_symmetric_set) {
8685     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);
8686     ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr);
8687     ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr);
8688   } else *flg = A->structurally_symmetric;
8689   PetscFunctionReturn(0);
8690 }
8691 
8692 /*@
8693    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8694        to be communicated to other processors during the MatAssemblyBegin/End() process
8695 
8696     Not collective
8697 
8698    Input Parameter:
8699 .   vec - the vector
8700 
8701    Output Parameters:
8702 +   nstash   - the size of the stash
8703 .   reallocs - the number of additional mallocs incurred.
8704 .   bnstash   - the size of the block stash
8705 -   breallocs - the number of additional mallocs incurred.in the block stash
8706 
8707    Level: advanced
8708 
8709 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8710 
8711 @*/
8712 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8713 {
8714   PetscErrorCode ierr;
8715 
8716   PetscFunctionBegin;
8717   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8718   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8719   PetscFunctionReturn(0);
8720 }
8721 
8722 /*@C
8723    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8724      parallel layout
8725 
8726    Collective on Mat
8727 
8728    Input Parameter:
8729 .  mat - the matrix
8730 
8731    Output Parameter:
8732 +   right - (optional) vector that the matrix can be multiplied against
8733 -   left - (optional) vector that the matrix vector product can be stored in
8734 
8735    Notes:
8736     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().
8737 
8738   Notes:
8739     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8740 
8741   Level: advanced
8742 
8743 .seealso: MatCreate(), VecDestroy()
8744 @*/
8745 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8746 {
8747   PetscErrorCode ierr;
8748 
8749   PetscFunctionBegin;
8750   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8751   PetscValidType(mat,1);
8752   if (mat->ops->getvecs) {
8753     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8754   } else {
8755     PetscInt rbs,cbs;
8756     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8757     if (right) {
8758       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8759       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8760       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8761       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8762       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8763       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8764     }
8765     if (left) {
8766       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8767       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8768       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8769       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8770       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8771       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8772     }
8773   }
8774   PetscFunctionReturn(0);
8775 }
8776 
8777 /*@C
8778    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8779      with default values.
8780 
8781    Not Collective
8782 
8783    Input Parameters:
8784 .    info - the MatFactorInfo data structure
8785 
8786 
8787    Notes:
8788     The solvers are generally used through the KSP and PC objects, for example
8789           PCLU, PCILU, PCCHOLESKY, PCICC
8790 
8791    Level: developer
8792 
8793 .seealso: MatFactorInfo
8794 
8795     Developer Note: fortran interface is not autogenerated as the f90
8796     interface defintion cannot be generated correctly [due to MatFactorInfo]
8797 
8798 @*/
8799 
8800 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8801 {
8802   PetscErrorCode ierr;
8803 
8804   PetscFunctionBegin;
8805   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8806   PetscFunctionReturn(0);
8807 }
8808 
8809 /*@
8810    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8811 
8812    Collective on Mat
8813 
8814    Input Parameters:
8815 +  mat - the factored matrix
8816 -  is - the index set defining the Schur indices (0-based)
8817 
8818    Notes:
8819     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8820 
8821    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8822 
8823    Level: developer
8824 
8825 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8826           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8827 
8828 @*/
8829 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8830 {
8831   PetscErrorCode ierr,(*f)(Mat,IS);
8832 
8833   PetscFunctionBegin;
8834   PetscValidType(mat,1);
8835   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8836   PetscValidType(is,2);
8837   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8838   PetscCheckSameComm(mat,1,is,2);
8839   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8840   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8841   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");
8842   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8843   ierr = (*f)(mat,is);CHKERRQ(ierr);
8844   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8845   PetscFunctionReturn(0);
8846 }
8847 
8848 /*@
8849   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8850 
8851    Logically Collective on Mat
8852 
8853    Input Parameters:
8854 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8855 .  S - location where to return the Schur complement, can be NULL
8856 -  status - the status of the Schur complement matrix, can be NULL
8857 
8858    Notes:
8859    You must call MatFactorSetSchurIS() before calling this routine.
8860 
8861    The routine provides a copy of the Schur matrix stored within the solver data structures.
8862    The caller must destroy the object when it is no longer needed.
8863    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8864 
8865    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)
8866 
8867    Developer Notes:
8868     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8869    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8870 
8871    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8872 
8873    Level: advanced
8874 
8875    References:
8876 
8877 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8878 @*/
8879 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8880 {
8881   PetscErrorCode ierr;
8882 
8883   PetscFunctionBegin;
8884   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8885   if (S) PetscValidPointer(S,2);
8886   if (status) PetscValidPointer(status,3);
8887   if (S) {
8888     PetscErrorCode (*f)(Mat,Mat*);
8889 
8890     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8891     if (f) {
8892       ierr = (*f)(F,S);CHKERRQ(ierr);
8893     } else {
8894       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8895     }
8896   }
8897   if (status) *status = F->schur_status;
8898   PetscFunctionReturn(0);
8899 }
8900 
8901 /*@
8902   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8903 
8904    Logically Collective on Mat
8905 
8906    Input Parameters:
8907 +  F - the factored matrix obtained by calling MatGetFactor()
8908 .  *S - location where to return the Schur complement, can be NULL
8909 -  status - the status of the Schur complement matrix, can be NULL
8910 
8911    Notes:
8912    You must call MatFactorSetSchurIS() before calling this routine.
8913 
8914    Schur complement mode is currently implemented for sequential matrices.
8915    The routine returns a the Schur Complement stored within the data strutures of the solver.
8916    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8917    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8918 
8919    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8920 
8921    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8922 
8923    Level: advanced
8924 
8925    References:
8926 
8927 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8928 @*/
8929 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8930 {
8931   PetscFunctionBegin;
8932   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8933   if (S) PetscValidPointer(S,2);
8934   if (status) PetscValidPointer(status,3);
8935   if (S) *S = F->schur;
8936   if (status) *status = F->schur_status;
8937   PetscFunctionReturn(0);
8938 }
8939 
8940 /*@
8941   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8942 
8943    Logically Collective on Mat
8944 
8945    Input Parameters:
8946 +  F - the factored matrix obtained by calling MatGetFactor()
8947 .  *S - location where the Schur complement is stored
8948 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8949 
8950    Notes:
8951 
8952    Level: advanced
8953 
8954    References:
8955 
8956 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8957 @*/
8958 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8959 {
8960   PetscErrorCode ierr;
8961 
8962   PetscFunctionBegin;
8963   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8964   if (S) {
8965     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8966     *S = NULL;
8967   }
8968   F->schur_status = status;
8969   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8970   PetscFunctionReturn(0);
8971 }
8972 
8973 /*@
8974   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8975 
8976    Logically Collective on Mat
8977 
8978    Input Parameters:
8979 +  F - the factored matrix obtained by calling MatGetFactor()
8980 .  rhs - location where the right hand side of the Schur complement system is stored
8981 -  sol - location where the solution of the Schur complement system has to be returned
8982 
8983    Notes:
8984    The sizes of the vectors should match the size of the Schur complement
8985 
8986    Must be called after MatFactorSetSchurIS()
8987 
8988    Level: advanced
8989 
8990    References:
8991 
8992 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8993 @*/
8994 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8995 {
8996   PetscErrorCode ierr;
8997 
8998   PetscFunctionBegin;
8999   PetscValidType(F,1);
9000   PetscValidType(rhs,2);
9001   PetscValidType(sol,3);
9002   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9003   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9004   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9005   PetscCheckSameComm(F,1,rhs,2);
9006   PetscCheckSameComm(F,1,sol,3);
9007   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9008   switch (F->schur_status) {
9009   case MAT_FACTOR_SCHUR_FACTORED:
9010     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9011     break;
9012   case MAT_FACTOR_SCHUR_INVERTED:
9013     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9014     break;
9015   default:
9016     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9017     break;
9018   }
9019   PetscFunctionReturn(0);
9020 }
9021 
9022 /*@
9023   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9024 
9025    Logically Collective on Mat
9026 
9027    Input Parameters:
9028 +  F - the factored matrix obtained by calling MatGetFactor()
9029 .  rhs - location where the right hand side of the Schur complement system is stored
9030 -  sol - location where the solution of the Schur complement system has to be returned
9031 
9032    Notes:
9033    The sizes of the vectors should match the size of the Schur complement
9034 
9035    Must be called after MatFactorSetSchurIS()
9036 
9037    Level: advanced
9038 
9039    References:
9040 
9041 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9042 @*/
9043 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9044 {
9045   PetscErrorCode ierr;
9046 
9047   PetscFunctionBegin;
9048   PetscValidType(F,1);
9049   PetscValidType(rhs,2);
9050   PetscValidType(sol,3);
9051   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9052   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9053   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9054   PetscCheckSameComm(F,1,rhs,2);
9055   PetscCheckSameComm(F,1,sol,3);
9056   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9057   switch (F->schur_status) {
9058   case MAT_FACTOR_SCHUR_FACTORED:
9059     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9060     break;
9061   case MAT_FACTOR_SCHUR_INVERTED:
9062     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9063     break;
9064   default:
9065     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9066     break;
9067   }
9068   PetscFunctionReturn(0);
9069 }
9070 
9071 /*@
9072   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9073 
9074    Logically Collective on Mat
9075 
9076    Input Parameters:
9077 .  F - the factored matrix obtained by calling MatGetFactor()
9078 
9079    Notes:
9080     Must be called after MatFactorSetSchurIS().
9081 
9082    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9083 
9084    Level: advanced
9085 
9086    References:
9087 
9088 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9089 @*/
9090 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9091 {
9092   PetscErrorCode ierr;
9093 
9094   PetscFunctionBegin;
9095   PetscValidType(F,1);
9096   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9097   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9098   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9099   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9100   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9101   PetscFunctionReturn(0);
9102 }
9103 
9104 /*@
9105   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9106 
9107    Logically Collective on Mat
9108 
9109    Input Parameters:
9110 .  F - the factored matrix obtained by calling MatGetFactor()
9111 
9112    Notes:
9113     Must be called after MatFactorSetSchurIS().
9114 
9115    Level: advanced
9116 
9117    References:
9118 
9119 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9120 @*/
9121 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9122 {
9123   PetscErrorCode ierr;
9124 
9125   PetscFunctionBegin;
9126   PetscValidType(F,1);
9127   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9128   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9129   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9130   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9131   PetscFunctionReturn(0);
9132 }
9133 
9134 /*@
9135    MatPtAP - Creates the matrix product C = P^T * A * P
9136 
9137    Neighbor-wise Collective on Mat
9138 
9139    Input Parameters:
9140 +  A - the matrix
9141 .  P - the projection matrix
9142 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9143 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9144           if the result is a dense matrix this is irrelevent
9145 
9146    Output Parameters:
9147 .  C - the product matrix
9148 
9149    Notes:
9150    C will be created and must be destroyed by the user with MatDestroy().
9151 
9152    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9153 
9154    Level: intermediate
9155 
9156 .seealso: MatMatMult(), MatRARt()
9157 @*/
9158 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9159 {
9160   PetscErrorCode ierr;
9161 
9162   PetscFunctionBegin;
9163   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9164 
9165   if (scall == MAT_INITIAL_MATRIX) {
9166     ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr);
9167     ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr);
9168     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9169     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9170 
9171     (*C)->product->api_user = PETSC_TRUE;
9172     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9173     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9174   } else {
9175     Mat_Product *product = (*C)->product;
9176     if (product) { /* user may chage input matrices A or B when REUSE */
9177       ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr);
9178     } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() or MatProductReplaceProduct() first");
9179   }
9180 
9181   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9182   if (A->symmetric_set && A->symmetric) {
9183     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9184   }
9185   PetscFunctionReturn(0);
9186 }
9187 
9188 /*@
9189    MatRARt - Creates the matrix product C = R * A * R^T
9190 
9191    Neighbor-wise Collective on Mat
9192 
9193    Input Parameters:
9194 +  A - the matrix
9195 .  R - the projection matrix
9196 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9197 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9198           if the result is a dense matrix this is irrelevent
9199 
9200    Output Parameters:
9201 .  C - the product matrix
9202 
9203    Notes:
9204    C will be created and must be destroyed by the user with MatDestroy().
9205 
9206    This routine is currently only implemented for pairs of AIJ matrices and classes
9207    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9208    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9209    We recommend using MatPtAP().
9210 
9211    Level: intermediate
9212 
9213 .seealso: MatMatMult(), MatPtAP()
9214 @*/
9215 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9216 {
9217   PetscErrorCode ierr;
9218 
9219   PetscFunctionBegin;
9220   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9221 
9222   if (scall == MAT_INITIAL_MATRIX) {
9223     ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr);
9224     ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr);
9225     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9226     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9227 
9228     (*C)->product->api_user = PETSC_TRUE;
9229     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9230     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9231   } else { /* scall == MAT_REUSE_MATRIX */
9232     Mat_Product *product = (*C)->product;
9233     if (product) {
9234       /* user may chage input matrices A or R when REUSE */
9235       ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr);
9236     } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() or MatProductReplaceProduct() first");
9237   }
9238 
9239   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9240   PetscFunctionReturn(0);
9241 }
9242 
9243 
9244 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9245 {
9246   PetscBool      clearproduct = PETSC_FALSE;
9247   PetscErrorCode ierr;
9248 
9249   PetscFunctionBegin;
9250   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9251 
9252   if (scall == MAT_INITIAL_MATRIX) {
9253     ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr);
9254     ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9255     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9256     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9257 
9258     (*C)->product->api_user = PETSC_TRUE;
9259     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9260     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9261   } else { /* scall == MAT_REUSE_MATRIX */
9262     Mat_Product *product = (*C)->product;
9263     if (!product) {
9264       /* user provide the dense matrix *C without calling MatProductCreate() */
9265       PetscBool seqdense,mpidense,dense;
9266 #if defined(PETSC_HAVE_CUDA)
9267       PetscBool seqdensecuda;
9268 #endif
9269       ierr = PetscObjectTypeCompare((PetscObject)(*C),MATSEQDENSE,&seqdense);CHKERRQ(ierr);
9270       ierr = PetscObjectTypeCompare((PetscObject)(*C),MATMPIDENSE,&mpidense);CHKERRQ(ierr);
9271       ierr = PetscObjectTypeCompare((PetscObject)(*C),MATDENSE,&dense);CHKERRQ(ierr);
9272 #if defined(PETSC_HAVE_CUDA)
9273       ierr = PetscObjectTypeCompare((PetscObject)(*C),MATSEQDENSECUDA,&seqdensecuda);CHKERRQ(ierr);
9274       if (seqdense || mpidense || dense || seqdensecuda) {
9275 #else
9276       if (seqdense || mpidense || dense) {
9277 #endif
9278         /* user wants to reuse an assembled dense matrix */
9279         /* Create product -- see MatCreateProduct() */
9280         ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr);
9281         product = (*C)->product;
9282         product->fill     = fill;
9283         product->api_user = PETSC_TRUE;
9284 
9285         ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9286         ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9287         ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9288       } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() or MatProductReplaceProduct() first");
9289       clearproduct = PETSC_TRUE;
9290     } else { /* user may chage input matrices A or B when REUSE */
9291       ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr);
9292     }
9293   }
9294   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9295   if (clearproduct) {
9296     ierr = MatProductClear(*C);CHKERRQ(ierr);
9297   }
9298   PetscFunctionReturn(0);
9299 }
9300 
9301 /*@
9302    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9303 
9304    Neighbor-wise Collective on Mat
9305 
9306    Input Parameters:
9307 +  A - the left matrix
9308 .  B - the right matrix
9309 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9310 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9311           if the result is a dense matrix this is irrelevent
9312 
9313    Output Parameters:
9314 .  C - the product matrix
9315 
9316    Notes:
9317    Unless scall is MAT_REUSE_MATRIX C will be created.
9318 
9319    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
9320    call to this function with MAT_INITIAL_MATRIX.
9321 
9322    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9323 
9324    If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic(C)/ReplaceMats(), and call MatProductNumeric() repeatedly.
9325 
9326    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.
9327 
9328    Level: intermediate
9329 
9330 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9331 @*/
9332 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9333 {
9334   PetscErrorCode ierr;
9335 
9336   PetscFunctionBegin;
9337   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr);
9338   PetscFunctionReturn(0);
9339 }
9340 
9341 /*@
9342    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9343 
9344    Neighbor-wise Collective on Mat
9345 
9346    Input Parameters:
9347 +  A - the left matrix
9348 .  B - the right matrix
9349 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9350 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9351 
9352    Output Parameters:
9353 .  C - the product matrix
9354 
9355    Notes:
9356    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9357 
9358    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9359 
9360   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9361    actually needed.
9362 
9363    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9364    and for pairs of MPIDense matrices.
9365 
9366    Options Database Keys:
9367 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9368                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9369                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9370 
9371    Level: intermediate
9372 
9373 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP()
9374 @*/
9375 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9376 {
9377   PetscErrorCode ierr;
9378 
9379   PetscFunctionBegin;
9380   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr);
9381   PetscFunctionReturn(0);
9382 }
9383 
9384 /*@
9385    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9386 
9387    Neighbor-wise Collective on Mat
9388 
9389    Input Parameters:
9390 +  A - the left matrix
9391 .  B - the right matrix
9392 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9393 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9394 
9395    Output Parameters:
9396 .  C - the product matrix
9397 
9398    Notes:
9399    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9400 
9401    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9402 
9403   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9404    actually needed.
9405 
9406    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9407    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9408 
9409    Level: intermediate
9410 
9411 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9412 @*/
9413 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9414 {
9415   PetscErrorCode ierr;
9416 
9417   PetscFunctionBegin;
9418   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr);
9419   PetscFunctionReturn(0);
9420 }
9421 
9422 /*@
9423    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9424 
9425    Neighbor-wise Collective on Mat
9426 
9427    Input Parameters:
9428 +  A - the left matrix
9429 .  B - the middle matrix
9430 .  C - the right matrix
9431 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9432 -  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
9433           if the result is a dense matrix this is irrelevent
9434 
9435    Output Parameters:
9436 .  D - the product matrix
9437 
9438    Notes:
9439    Unless scall is MAT_REUSE_MATRIX D will be created.
9440 
9441    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9442 
9443    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9444    actually needed.
9445 
9446    If you have many matrices with the same non-zero structure to multiply, you
9447    should use MAT_REUSE_MATRIX in all calls but the first or
9448 
9449    Level: intermediate
9450 
9451 .seealso: MatMatMult, MatPtAP()
9452 @*/
9453 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9454 {
9455   PetscErrorCode ierr;
9456 
9457   PetscFunctionBegin;
9458   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9459 
9460   if (scall == MAT_INITIAL_MATRIX) {
9461     ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr);
9462     ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr);
9463     ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr);
9464     ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr);
9465 
9466     (*D)->product->api_user = PETSC_TRUE;
9467     ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr);
9468 
9469     ierr = MatProductSymbolic(*D);CHKERRQ(ierr);
9470   } else { /* user may chage input matrices when REUSE */
9471     ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr);
9472   }
9473 
9474   ierr = MatProductNumeric(*D);CHKERRQ(ierr);
9475   PetscFunctionReturn(0);
9476 }
9477 
9478 /*@
9479    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9480 
9481    Collective on Mat
9482 
9483    Input Parameters:
9484 +  mat - the matrix
9485 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9486 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9487 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9488 
9489    Output Parameter:
9490 .  matredundant - redundant matrix
9491 
9492    Notes:
9493    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9494    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9495 
9496    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9497    calling it.
9498 
9499    Level: advanced
9500 
9501 
9502 .seealso: MatDestroy()
9503 @*/
9504 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9505 {
9506   PetscErrorCode ierr;
9507   MPI_Comm       comm;
9508   PetscMPIInt    size;
9509   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9510   Mat_Redundant  *redund=NULL;
9511   PetscSubcomm   psubcomm=NULL;
9512   MPI_Comm       subcomm_in=subcomm;
9513   Mat            *matseq;
9514   IS             isrow,iscol;
9515   PetscBool      newsubcomm=PETSC_FALSE;
9516 
9517   PetscFunctionBegin;
9518   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9519   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9520     PetscValidPointer(*matredundant,5);
9521     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9522   }
9523 
9524   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9525   if (size == 1 || nsubcomm == 1) {
9526     if (reuse == MAT_INITIAL_MATRIX) {
9527       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9528     } else {
9529       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");
9530       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9531     }
9532     PetscFunctionReturn(0);
9533   }
9534 
9535   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9536   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9537   MatCheckPreallocated(mat,1);
9538 
9539   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9540   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9541     /* create psubcomm, then get subcomm */
9542     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9543     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9544     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9545 
9546     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9547     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9548     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9549     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9550     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9551     newsubcomm = PETSC_TRUE;
9552     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9553   }
9554 
9555   /* get isrow, iscol and a local sequential matrix matseq[0] */
9556   if (reuse == MAT_INITIAL_MATRIX) {
9557     mloc_sub = PETSC_DECIDE;
9558     nloc_sub = PETSC_DECIDE;
9559     if (bs < 1) {
9560       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9561       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9562     } else {
9563       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9564       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
9565     }
9566     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9567     rstart = rend - mloc_sub;
9568     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9569     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9570   } else { /* reuse == MAT_REUSE_MATRIX */
9571     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");
9572     /* retrieve subcomm */
9573     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9574     redund = (*matredundant)->redundant;
9575     isrow  = redund->isrow;
9576     iscol  = redund->iscol;
9577     matseq = redund->matseq;
9578   }
9579   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9580 
9581   /* get matredundant over subcomm */
9582   if (reuse == MAT_INITIAL_MATRIX) {
9583     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
9584 
9585     /* create a supporting struct and attach it to C for reuse */
9586     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9587     (*matredundant)->redundant = redund;
9588     redund->isrow              = isrow;
9589     redund->iscol              = iscol;
9590     redund->matseq             = matseq;
9591     if (newsubcomm) {
9592       redund->subcomm          = subcomm;
9593     } else {
9594       redund->subcomm          = MPI_COMM_NULL;
9595     }
9596   } else {
9597     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
9598   }
9599   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9600   PetscFunctionReturn(0);
9601 }
9602 
9603 /*@C
9604    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9605    a given 'mat' object. Each submatrix can span multiple procs.
9606 
9607    Collective on Mat
9608 
9609    Input Parameters:
9610 +  mat - the matrix
9611 .  subcomm - the subcommunicator obtained by com_split(comm)
9612 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9613 
9614    Output Parameter:
9615 .  subMat - 'parallel submatrices each spans a given subcomm
9616 
9617   Notes:
9618   The submatrix partition across processors is dictated by 'subComm' a
9619   communicator obtained by com_split(comm). The comm_split
9620   is not restriced to be grouped with consecutive original ranks.
9621 
9622   Due the comm_split() usage, the parallel layout of the submatrices
9623   map directly to the layout of the original matrix [wrt the local
9624   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9625   into the 'DiagonalMat' of the subMat, hence it is used directly from
9626   the subMat. However the offDiagMat looses some columns - and this is
9627   reconstructed with MatSetValues()
9628 
9629   Level: advanced
9630 
9631 
9632 .seealso: MatCreateSubMatrices()
9633 @*/
9634 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9635 {
9636   PetscErrorCode ierr;
9637   PetscMPIInt    commsize,subCommSize;
9638 
9639   PetscFunctionBegin;
9640   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
9641   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9642   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9643 
9644   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");
9645   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9646   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9647   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9648   PetscFunctionReturn(0);
9649 }
9650 
9651 /*@
9652    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9653 
9654    Not Collective
9655 
9656    Input Arguments:
9657 +  mat - matrix to extract local submatrix from
9658 .  isrow - local row indices for submatrix
9659 -  iscol - local column indices for submatrix
9660 
9661    Output Arguments:
9662 .  submat - the submatrix
9663 
9664    Level: intermediate
9665 
9666    Notes:
9667    The submat should be returned with MatRestoreLocalSubMatrix().
9668 
9669    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9670    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9671 
9672    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9673    MatSetValuesBlockedLocal() will also be implemented.
9674 
9675    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
9676    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
9677 
9678 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
9679 @*/
9680 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9681 {
9682   PetscErrorCode ierr;
9683 
9684   PetscFunctionBegin;
9685   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9686   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9687   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9688   PetscCheckSameComm(isrow,2,iscol,3);
9689   PetscValidPointer(submat,4);
9690   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
9691 
9692   if (mat->ops->getlocalsubmatrix) {
9693     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9694   } else {
9695     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9696   }
9697   PetscFunctionReturn(0);
9698 }
9699 
9700 /*@
9701    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9702 
9703    Not Collective
9704 
9705    Input Arguments:
9706    mat - matrix to extract local submatrix from
9707    isrow - local row indices for submatrix
9708    iscol - local column indices for submatrix
9709    submat - the submatrix
9710 
9711    Level: intermediate
9712 
9713 .seealso: MatGetLocalSubMatrix()
9714 @*/
9715 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9716 {
9717   PetscErrorCode ierr;
9718 
9719   PetscFunctionBegin;
9720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9721   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9722   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9723   PetscCheckSameComm(isrow,2,iscol,3);
9724   PetscValidPointer(submat,4);
9725   if (*submat) {
9726     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
9727   }
9728 
9729   if (mat->ops->restorelocalsubmatrix) {
9730     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9731   } else {
9732     ierr = MatDestroy(submat);CHKERRQ(ierr);
9733   }
9734   *submat = NULL;
9735   PetscFunctionReturn(0);
9736 }
9737 
9738 /* --------------------------------------------------------*/
9739 /*@
9740    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
9741 
9742    Collective on Mat
9743 
9744    Input Parameter:
9745 .  mat - the matrix
9746 
9747    Output Parameter:
9748 .  is - if any rows have zero diagonals this contains the list of them
9749 
9750    Level: developer
9751 
9752 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9753 @*/
9754 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9755 {
9756   PetscErrorCode ierr;
9757 
9758   PetscFunctionBegin;
9759   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9760   PetscValidType(mat,1);
9761   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9762   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9763 
9764   if (!mat->ops->findzerodiagonals) {
9765     Vec                diag;
9766     const PetscScalar *a;
9767     PetscInt          *rows;
9768     PetscInt           rStart, rEnd, r, nrow = 0;
9769 
9770     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
9771     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
9772     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
9773     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
9774     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
9775     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
9776     nrow = 0;
9777     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
9778     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
9779     ierr = VecDestroy(&diag);CHKERRQ(ierr);
9780     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
9781   } else {
9782     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
9783   }
9784   PetscFunctionReturn(0);
9785 }
9786 
9787 /*@
9788    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
9789 
9790    Collective on Mat
9791 
9792    Input Parameter:
9793 .  mat - the matrix
9794 
9795    Output Parameter:
9796 .  is - contains the list of rows with off block diagonal entries
9797 
9798    Level: developer
9799 
9800 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9801 @*/
9802 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9803 {
9804   PetscErrorCode ierr;
9805 
9806   PetscFunctionBegin;
9807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9808   PetscValidType(mat,1);
9809   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9810   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9811 
9812   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);
9813   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
9814   PetscFunctionReturn(0);
9815 }
9816 
9817 /*@C
9818   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9819 
9820   Collective on Mat
9821 
9822   Input Parameters:
9823 . mat - the matrix
9824 
9825   Output Parameters:
9826 . values - the block inverses in column major order (FORTRAN-like)
9827 
9828    Note:
9829    This routine is not available from Fortran.
9830 
9831   Level: advanced
9832 
9833 .seealso: MatInvertBockDiagonalMat
9834 @*/
9835 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9836 {
9837   PetscErrorCode ierr;
9838 
9839   PetscFunctionBegin;
9840   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9841   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9842   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9843   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
9844   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9845   PetscFunctionReturn(0);
9846 }
9847 
9848 /*@C
9849   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
9850 
9851   Collective on Mat
9852 
9853   Input Parameters:
9854 + mat - the matrix
9855 . nblocks - the number of blocks
9856 - bsizes - the size of each block
9857 
9858   Output Parameters:
9859 . values - the block inverses in column major order (FORTRAN-like)
9860 
9861    Note:
9862    This routine is not available from Fortran.
9863 
9864   Level: advanced
9865 
9866 .seealso: MatInvertBockDiagonal()
9867 @*/
9868 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
9869 {
9870   PetscErrorCode ierr;
9871 
9872   PetscFunctionBegin;
9873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9874   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9875   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9876   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
9877   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
9878   PetscFunctionReturn(0);
9879 }
9880 
9881 /*@
9882   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
9883 
9884   Collective on Mat
9885 
9886   Input Parameters:
9887 . A - the matrix
9888 
9889   Output Parameters:
9890 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
9891 
9892   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
9893 
9894   Level: advanced
9895 
9896 .seealso: MatInvertBockDiagonal()
9897 @*/
9898 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
9899 {
9900   PetscErrorCode     ierr;
9901   const PetscScalar *vals;
9902   PetscInt          *dnnz;
9903   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
9904 
9905   PetscFunctionBegin;
9906   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
9907   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
9908   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
9909   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
9910   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
9911   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
9912   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
9913   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
9914   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
9915   ierr = PetscFree(dnnz);CHKERRQ(ierr);
9916   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
9917   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
9918   for (i = rstart/bs; i < rend/bs; i++) {
9919     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
9920   }
9921   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9922   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9923   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
9924   PetscFunctionReturn(0);
9925 }
9926 
9927 /*@C
9928     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9929     via MatTransposeColoringCreate().
9930 
9931     Collective on MatTransposeColoring
9932 
9933     Input Parameter:
9934 .   c - coloring context
9935 
9936     Level: intermediate
9937 
9938 .seealso: MatTransposeColoringCreate()
9939 @*/
9940 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9941 {
9942   PetscErrorCode       ierr;
9943   MatTransposeColoring matcolor=*c;
9944 
9945   PetscFunctionBegin;
9946   if (!matcolor) PetscFunctionReturn(0);
9947   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9948 
9949   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
9950   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
9951   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
9952   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9953   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9954   if (matcolor->brows>0) {
9955     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
9956   }
9957   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9958   PetscFunctionReturn(0);
9959 }
9960 
9961 /*@C
9962     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9963     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9964     MatTransposeColoring to sparse B.
9965 
9966     Collective on MatTransposeColoring
9967 
9968     Input Parameters:
9969 +   B - sparse matrix B
9970 .   Btdense - symbolic dense matrix B^T
9971 -   coloring - coloring context created with MatTransposeColoringCreate()
9972 
9973     Output Parameter:
9974 .   Btdense - dense matrix B^T
9975 
9976     Level: advanced
9977 
9978      Notes:
9979     These are used internally for some implementations of MatRARt()
9980 
9981 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
9982 
9983 @*/
9984 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9985 {
9986   PetscErrorCode ierr;
9987 
9988   PetscFunctionBegin;
9989   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9990   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9991   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9992 
9993   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9994   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9995   PetscFunctionReturn(0);
9996 }
9997 
9998 /*@C
9999     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10000     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10001     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10002     Csp from Cden.
10003 
10004     Collective on MatTransposeColoring
10005 
10006     Input Parameters:
10007 +   coloring - coloring context created with MatTransposeColoringCreate()
10008 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10009 
10010     Output Parameter:
10011 .   Csp - sparse matrix
10012 
10013     Level: advanced
10014 
10015      Notes:
10016     These are used internally for some implementations of MatRARt()
10017 
10018 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10019 
10020 @*/
10021 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10022 {
10023   PetscErrorCode ierr;
10024 
10025   PetscFunctionBegin;
10026   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10027   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10028   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10029 
10030   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10031   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10032   ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10033   ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10034   PetscFunctionReturn(0);
10035 }
10036 
10037 /*@C
10038    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10039 
10040    Collective on Mat
10041 
10042    Input Parameters:
10043 +  mat - the matrix product C
10044 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10045 
10046     Output Parameter:
10047 .   color - the new coloring context
10048 
10049     Level: intermediate
10050 
10051 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10052            MatTransColoringApplyDenToSp()
10053 @*/
10054 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10055 {
10056   MatTransposeColoring c;
10057   MPI_Comm             comm;
10058   PetscErrorCode       ierr;
10059 
10060   PetscFunctionBegin;
10061   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10062   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10063   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10064 
10065   c->ctype = iscoloring->ctype;
10066   if (mat->ops->transposecoloringcreate) {
10067     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10068   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10069 
10070   *color = c;
10071   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10072   PetscFunctionReturn(0);
10073 }
10074 
10075 /*@
10076       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10077         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10078         same, otherwise it will be larger
10079 
10080      Not Collective
10081 
10082   Input Parameter:
10083 .    A  - the matrix
10084 
10085   Output Parameter:
10086 .    state - the current state
10087 
10088   Notes:
10089     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10090          different matrices
10091 
10092   Level: intermediate
10093 
10094 @*/
10095 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10096 {
10097   PetscFunctionBegin;
10098   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10099   *state = mat->nonzerostate;
10100   PetscFunctionReturn(0);
10101 }
10102 
10103 /*@
10104       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10105                  matrices from each processor
10106 
10107     Collective
10108 
10109    Input Parameters:
10110 +    comm - the communicators the parallel matrix will live on
10111 .    seqmat - the input sequential matrices
10112 .    n - number of local columns (or PETSC_DECIDE)
10113 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10114 
10115    Output Parameter:
10116 .    mpimat - the parallel matrix generated
10117 
10118     Level: advanced
10119 
10120    Notes:
10121     The number of columns of the matrix in EACH processor MUST be the same.
10122 
10123 @*/
10124 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10125 {
10126   PetscErrorCode ierr;
10127 
10128   PetscFunctionBegin;
10129   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10130   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");
10131 
10132   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10133   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10134   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10135   PetscFunctionReturn(0);
10136 }
10137 
10138 /*@
10139      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10140                  ranks' ownership ranges.
10141 
10142     Collective on A
10143 
10144    Input Parameters:
10145 +    A   - the matrix to create subdomains from
10146 -    N   - requested number of subdomains
10147 
10148 
10149    Output Parameters:
10150 +    n   - number of subdomains resulting on this rank
10151 -    iss - IS list with indices of subdomains on this rank
10152 
10153     Level: advanced
10154 
10155     Notes:
10156     number of subdomains must be smaller than the communicator size
10157 @*/
10158 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10159 {
10160   MPI_Comm        comm,subcomm;
10161   PetscMPIInt     size,rank,color;
10162   PetscInt        rstart,rend,k;
10163   PetscErrorCode  ierr;
10164 
10165   PetscFunctionBegin;
10166   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10167   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10168   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10169   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);
10170   *n = 1;
10171   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10172   color = rank/k;
10173   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10174   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10175   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10176   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10177   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10178   PetscFunctionReturn(0);
10179 }
10180 
10181 /*@
10182    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10183 
10184    If the interpolation and restriction operators are the same, uses MatPtAP.
10185    If they are not the same, use MatMatMatMult.
10186 
10187    Once the coarse grid problem is constructed, correct for interpolation operators
10188    that are not of full rank, which can legitimately happen in the case of non-nested
10189    geometric multigrid.
10190 
10191    Input Parameters:
10192 +  restrct - restriction operator
10193 .  dA - fine grid matrix
10194 .  interpolate - interpolation operator
10195 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10196 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10197 
10198    Output Parameters:
10199 .  A - the Galerkin coarse matrix
10200 
10201    Options Database Key:
10202 .  -pc_mg_galerkin <both,pmat,mat,none>
10203 
10204    Level: developer
10205 
10206 .seealso: MatPtAP(), MatMatMatMult()
10207 @*/
10208 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10209 {
10210   PetscErrorCode ierr;
10211   IS             zerorows;
10212   Vec            diag;
10213 
10214   PetscFunctionBegin;
10215   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10216   /* Construct the coarse grid matrix */
10217   if (interpolate == restrct) {
10218     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10219   } else {
10220     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10221   }
10222 
10223   /* If the interpolation matrix is not of full rank, A will have zero rows.
10224      This can legitimately happen in the case of non-nested geometric multigrid.
10225      In that event, we set the rows of the matrix to the rows of the identity,
10226      ignoring the equations (as the RHS will also be zero). */
10227 
10228   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10229 
10230   if (zerorows != NULL) { /* if there are any zero rows */
10231     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10232     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10233     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10234     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10235     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10236     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10237   }
10238   PetscFunctionReturn(0);
10239 }
10240 
10241 /*@C
10242     MatSetOperation - Allows user to set a matrix operation for any matrix type
10243 
10244    Logically Collective on Mat
10245 
10246     Input Parameters:
10247 +   mat - the matrix
10248 .   op - the name of the operation
10249 -   f - the function that provides the operation
10250 
10251    Level: developer
10252 
10253     Usage:
10254 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10255 $      ierr = MatCreateXXX(comm,...&A);
10256 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10257 
10258     Notes:
10259     See the file include/petscmat.h for a complete list of matrix
10260     operations, which all have the form MATOP_<OPERATION>, where
10261     <OPERATION> is the name (in all capital letters) of the
10262     user interface routine (e.g., MatMult() -> MATOP_MULT).
10263 
10264     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10265     sequence as the usual matrix interface routines, since they
10266     are intended to be accessed via the usual matrix interface
10267     routines, e.g.,
10268 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10269 
10270     In particular each function MUST return an error code of 0 on success and
10271     nonzero on failure.
10272 
10273     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10274 
10275 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10276 @*/
10277 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10278 {
10279   PetscFunctionBegin;
10280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10281   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10282     mat->ops->viewnative = mat->ops->view;
10283   }
10284   (((void(**)(void))mat->ops)[op]) = f;
10285   PetscFunctionReturn(0);
10286 }
10287 
10288 /*@C
10289     MatGetOperation - Gets a matrix operation for any matrix type.
10290 
10291     Not Collective
10292 
10293     Input Parameters:
10294 +   mat - the matrix
10295 -   op - the name of the operation
10296 
10297     Output Parameter:
10298 .   f - the function that provides the operation
10299 
10300     Level: developer
10301 
10302     Usage:
10303 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10304 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10305 
10306     Notes:
10307     See the file include/petscmat.h for a complete list of matrix
10308     operations, which all have the form MATOP_<OPERATION>, where
10309     <OPERATION> is the name (in all capital letters) of the
10310     user interface routine (e.g., MatMult() -> MATOP_MULT).
10311 
10312     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10313 
10314 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10315 @*/
10316 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10317 {
10318   PetscFunctionBegin;
10319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10320   *f = (((void (**)(void))mat->ops)[op]);
10321   PetscFunctionReturn(0);
10322 }
10323 
10324 /*@
10325     MatHasOperation - Determines whether the given matrix supports the particular
10326     operation.
10327 
10328    Not Collective
10329 
10330    Input Parameters:
10331 +  mat - the matrix
10332 -  op - the operation, for example, MATOP_GET_DIAGONAL
10333 
10334    Output Parameter:
10335 .  has - either PETSC_TRUE or PETSC_FALSE
10336 
10337    Level: advanced
10338 
10339    Notes:
10340    See the file include/petscmat.h for a complete list of matrix
10341    operations, which all have the form MATOP_<OPERATION>, where
10342    <OPERATION> is the name (in all capital letters) of the
10343    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10344 
10345 .seealso: MatCreateShell()
10346 @*/
10347 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10348 {
10349   PetscErrorCode ierr;
10350 
10351   PetscFunctionBegin;
10352   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10353   PetscValidType(mat,1);
10354   PetscValidPointer(has,3);
10355   if (mat->ops->hasoperation) {
10356     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10357   } else {
10358     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10359     else {
10360       *has = PETSC_FALSE;
10361       if (op == MATOP_CREATE_SUBMATRIX) {
10362         PetscMPIInt size;
10363 
10364         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10365         if (size == 1) {
10366           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10367         }
10368       }
10369     }
10370   }
10371   PetscFunctionReturn(0);
10372 }
10373 
10374 /*@
10375     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10376     of the matrix are congruent
10377 
10378    Collective on mat
10379 
10380    Input Parameters:
10381 .  mat - the matrix
10382 
10383    Output Parameter:
10384 .  cong - either PETSC_TRUE or PETSC_FALSE
10385 
10386    Level: beginner
10387 
10388    Notes:
10389 
10390 .seealso: MatCreate(), MatSetSizes()
10391 @*/
10392 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10393 {
10394   PetscErrorCode ierr;
10395 
10396   PetscFunctionBegin;
10397   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10398   PetscValidType(mat,1);
10399   PetscValidPointer(cong,2);
10400   if (!mat->rmap || !mat->cmap) {
10401     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10402     PetscFunctionReturn(0);
10403   }
10404   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10405     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10406     if (*cong) mat->congruentlayouts = 1;
10407     else       mat->congruentlayouts = 0;
10408   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10409   PetscFunctionReturn(0);
10410 }
10411 
10412 /*@
10413     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
10414     e.g., matrx product of MatPtAP.
10415 
10416    Collective on mat
10417 
10418    Input Parameters:
10419 .  mat - the matrix
10420 
10421    Output Parameter:
10422 .  mat - the matrix with intermediate data structures released
10423 
10424    Level: advanced
10425 
10426    Notes:
10427 
10428 .seealso: MatPtAP(), MatMatMult()
10429 @*/
10430 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
10431 {
10432   PetscErrorCode ierr;
10433 
10434   PetscFunctionBegin;
10435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10436   PetscValidType(mat,1);
10437   if (mat->ops->freeintermediatedatastructures) {
10438     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
10439   }
10440   PetscFunctionReturn(0);
10441 }
10442