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