xref: /petsc/src/mat/interface/matrix.c (revision 245d98336dcf84d7e5386ee5cb055ed89e78f1a7)
1 /*
2    This is where the abstract matrix operations are defined
3 */
4 
5 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
6 #include <petsc/private/isimpl.h>
7 #include <petsc/private/vecimpl.h>
8 
9 /* Logging support */
10 PetscClassId MAT_CLASSID;
11 PetscClassId MAT_COLORING_CLASSID;
12 PetscClassId MAT_FDCOLORING_CLASSID;
13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14 
15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
23 PetscLogEvent MAT_TransposeColoringCreate;
24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33 PetscLogEvent MAT_GetMultiProcBlock;
34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
35 PetscLogEvent MAT_ViennaCLCopyToGPU;
36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS;
39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
40 
41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
42 
43 /*@
44    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations,
45                   for sparse matrices that already have locations it fills the locations with random numbers
46 
47    Logically Collective on Mat
48 
49    Input Parameters:
50 +  x  - the matrix
51 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52           it will create one internally.
53 
54    Output Parameter:
55 .  x  - the matrix
56 
57    Example of Usage:
58 .vb
59      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60      MatSetRandom(x,rctx);
61      PetscRandomDestroy(rctx);
62 .ve
63 
64    Level: intermediate
65 
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name);
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391   PetscFunctionReturn(0);
392 }
393 
394 /*@C
395    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
396 
397    Collective on Mat
398 
399    Input Parameter:
400 .  mat - the matrix
401 
402    Output Parameters:
403 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
404 -   ghosts - the global indices of the ghost points
405 
406    Notes:
407     the nghosts and ghosts are suitable to pass into VecCreateGhost()
408 
409    Level: advanced
410 
411 @*/
412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
413 {
414   PetscErrorCode ierr;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
418   PetscValidType(mat,1);
419   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
420   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
421   if (!mat->ops->getghosts) {
422     if (nghosts) *nghosts = 0;
423     if (ghosts) *ghosts = 0;
424   } else {
425     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
426   }
427   PetscFunctionReturn(0);
428 }
429 
430 
431 /*@
432    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
433 
434    Logically Collective on Mat
435 
436    Input Parameters:
437 .  mat - the matrix
438 
439    Level: advanced
440 
441 
442 .seealso: MatRealPart()
443 @*/
444 PetscErrorCode MatImaginaryPart(Mat mat)
445 {
446   PetscErrorCode ierr;
447 
448   PetscFunctionBegin;
449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
450   PetscValidType(mat,1);
451   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
452   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
453   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
454   MatCheckPreallocated(mat,1);
455   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
456   PetscFunctionReturn(0);
457 }
458 
459 /*@
460    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
461 
462    Not Collective
463 
464    Input Parameter:
465 .  mat - the matrix
466 
467    Output Parameters:
468 +  missing - is any diagonal missing
469 -  dd - first diagonal entry that is missing (optional) on this process
470 
471    Level: advanced
472 
473 
474 .seealso: MatRealPart()
475 @*/
476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
477 {
478   PetscErrorCode ierr;
479 
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
482   PetscValidType(mat,1);
483   PetscValidPointer(missing,2);
484   if (!mat->assembled) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name);
485   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
486   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
487   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
488   PetscFunctionReturn(0);
489 }
490 
491 /*@C
492    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
493    for each row that you get to ensure that your application does
494    not bleed memory.
495 
496    Not Collective
497 
498    Input Parameters:
499 +  mat - the matrix
500 -  row - the row to get
501 
502    Output Parameters:
503 +  ncols -  if not NULL, the number of nonzeros in the row
504 .  cols - if not NULL, the column numbers
505 -  vals - if not NULL, the values
506 
507    Notes:
508    This routine is provided for people who need to have direct access
509    to the structure of a matrix.  We hope that we provide enough
510    high-level matrix routines that few users will need it.
511 
512    MatGetRow() always returns 0-based column indices, regardless of
513    whether the internal representation is 0-based (default) or 1-based.
514 
515    For better efficiency, set cols and/or vals to NULL if you do
516    not wish to extract these quantities.
517 
518    The user can only examine the values extracted with MatGetRow();
519    the values cannot be altered.  To change the matrix entries, one
520    must use MatSetValues().
521 
522    You can only have one call to MatGetRow() outstanding for a particular
523    matrix at a time, per processor. MatGetRow() can only obtain rows
524    associated with the given processor, it cannot get rows from the
525    other processors; for that we suggest using MatCreateSubMatrices(), then
526    MatGetRow() on the submatrix. The row index passed to MatGetRow()
527    is in the global number of rows.
528 
529    Fortran Notes:
530    The calling sequence from Fortran is
531 .vb
532    MatGetRow(matrix,row,ncols,cols,values,ierr)
533          Mat     matrix (input)
534          integer row    (input)
535          integer ncols  (output)
536          integer cols(maxcols) (output)
537          double precision (or double complex) values(maxcols) output
538 .ve
539    where maxcols >= maximum nonzeros in any row of the matrix.
540 
541 
542    Caution:
543    Do not try to change the contents of the output arrays (cols and vals).
544    In some cases, this may corrupt the matrix.
545 
546    Level: advanced
547 
548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
549 @*/
550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
551 {
552   PetscErrorCode ierr;
553   PetscInt       incols;
554 
555   PetscFunctionBegin;
556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
557   PetscValidType(mat,1);
558   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
559   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
560   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
561   MatCheckPreallocated(mat,1);
562   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
563   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
564   if (ncols) *ncols = incols;
565   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
566   PetscFunctionReturn(0);
567 }
568 
569 /*@
570    MatConjugate - replaces the matrix values with their complex conjugates
571 
572    Logically Collective on Mat
573 
574    Input Parameters:
575 .  mat - the matrix
576 
577    Level: advanced
578 
579 .seealso:  VecConjugate()
580 @*/
581 PetscErrorCode MatConjugate(Mat mat)
582 {
583 #if defined(PETSC_USE_COMPLEX)
584   PetscErrorCode ierr;
585 
586   PetscFunctionBegin;
587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
588   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
589   if (!mat->ops->conjugate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name);
590   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
591 #else
592   PetscFunctionBegin;
593 #endif
594   PetscFunctionReturn(0);
595 }
596 
597 /*@C
598    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
599 
600    Not Collective
601 
602    Input Parameters:
603 +  mat - the matrix
604 .  row - the row to get
605 .  ncols, cols - the number of nonzeros and their columns
606 -  vals - if nonzero the column values
607 
608    Notes:
609    This routine should be called after you have finished examining the entries.
610 
611    This routine zeros out ncols, cols, and vals. This is to prevent accidental
612    us of the array after it has been restored. If you pass NULL, it will
613    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
614 
615    Fortran Notes:
616    The calling sequence from Fortran is
617 .vb
618    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
619       Mat     matrix (input)
620       integer row    (input)
621       integer ncols  (output)
622       integer cols(maxcols) (output)
623       double precision (or double complex) values(maxcols) output
624 .ve
625    Where maxcols >= maximum nonzeros in any row of the matrix.
626 
627    In Fortran MatRestoreRow() MUST be called after MatGetRow()
628    before another call to MatGetRow() can be made.
629 
630    Level: advanced
631 
632 .seealso:  MatGetRow()
633 @*/
634 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
635 {
636   PetscErrorCode ierr;
637 
638   PetscFunctionBegin;
639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
640   if (ncols) PetscValidIntPointer(ncols,3);
641   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
642   if (!mat->ops->restorerow) PetscFunctionReturn(0);
643   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
644   if (ncols) *ncols = 0;
645   if (cols)  *cols = NULL;
646   if (vals)  *vals = NULL;
647   PetscFunctionReturn(0);
648 }
649 
650 /*@
651    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
652    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
653 
654    Not Collective
655 
656    Input Parameters:
657 .  mat - the matrix
658 
659    Notes:
660    The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format.
661 
662    Level: advanced
663 
664 .seealso: MatRestoreRowUpperTriangular()
665 @*/
666 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
667 {
668   PetscErrorCode ierr;
669 
670   PetscFunctionBegin;
671   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
672   PetscValidType(mat,1);
673   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
674   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
675   MatCheckPreallocated(mat,1);
676   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
677   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
678   PetscFunctionReturn(0);
679 }
680 
681 /*@
682    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
683 
684    Not Collective
685 
686    Input Parameters:
687 .  mat - the matrix
688 
689    Notes:
690    This routine should be called after you have finished MatGetRow/MatRestoreRow().
691 
692 
693    Level: advanced
694 
695 .seealso:  MatGetRowUpperTriangular()
696 @*/
697 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
698 {
699   PetscErrorCode ierr;
700 
701   PetscFunctionBegin;
702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
703   PetscValidType(mat,1);
704   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
705   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
706   MatCheckPreallocated(mat,1);
707   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
708   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
709   PetscFunctionReturn(0);
710 }
711 
712 /*@C
713    MatSetOptionsPrefix - Sets the prefix used for searching for all
714    Mat options in the database.
715 
716    Logically Collective on Mat
717 
718    Input Parameter:
719 +  A - the Mat context
720 -  prefix - the prefix to prepend to all option names
721 
722    Notes:
723    A hyphen (-) must NOT be given at the beginning of the prefix name.
724    The first character of all runtime options is AUTOMATICALLY the hyphen.
725 
726    Level: advanced
727 
728 .seealso: MatSetFromOptions()
729 @*/
730 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
731 {
732   PetscErrorCode ierr;
733 
734   PetscFunctionBegin;
735   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
736   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
737   PetscFunctionReturn(0);
738 }
739 
740 /*@C
741    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
742    Mat options in the database.
743 
744    Logically Collective on Mat
745 
746    Input Parameters:
747 +  A - the Mat context
748 -  prefix - the prefix to prepend to all option names
749 
750    Notes:
751    A hyphen (-) must NOT be given at the beginning of the prefix name.
752    The first character of all runtime options is AUTOMATICALLY the hyphen.
753 
754    Level: advanced
755 
756 .seealso: MatGetOptionsPrefix()
757 @*/
758 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
759 {
760   PetscErrorCode ierr;
761 
762   PetscFunctionBegin;
763   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
764   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
765   PetscFunctionReturn(0);
766 }
767 
768 /*@C
769    MatGetOptionsPrefix - Sets the prefix used for searching for all
770    Mat options in the database.
771 
772    Not Collective
773 
774    Input Parameter:
775 .  A - the Mat context
776 
777    Output Parameter:
778 .  prefix - pointer to the prefix string used
779 
780    Notes:
781     On the fortran side, the user should pass in a string 'prefix' of
782    sufficient length to hold the prefix.
783 
784    Level: advanced
785 
786 .seealso: MatAppendOptionsPrefix()
787 @*/
788 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
789 {
790   PetscErrorCode ierr;
791 
792   PetscFunctionBegin;
793   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
794   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
795   PetscFunctionReturn(0);
796 }
797 
798 /*@
799    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
800 
801    Collective on Mat
802 
803    Input Parameters:
804 .  A - the Mat context
805 
806    Notes:
807    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
808    Currently support MPIAIJ and SEQAIJ.
809 
810    Level: beginner
811 
812 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
813 @*/
814 PetscErrorCode MatResetPreallocation(Mat A)
815 {
816   PetscErrorCode ierr;
817 
818   PetscFunctionBegin;
819   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
820   PetscValidType(A,1);
821   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
822   PetscFunctionReturn(0);
823 }
824 
825 
826 /*@
827    MatSetUp - Sets up the internal matrix data structures for later use.
828 
829    Collective on Mat
830 
831    Input Parameters:
832 .  A - the Mat context
833 
834    Notes:
835    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
836 
837    If a suitable preallocation routine is used, this function does not need to be called.
838 
839    See the Performance chapter of the PETSc users manual for how to preallocate matrices
840 
841    Level: beginner
842 
843 .seealso: MatCreate(), MatDestroy()
844 @*/
845 PetscErrorCode MatSetUp(Mat A)
846 {
847   PetscMPIInt    size;
848   PetscErrorCode ierr;
849 
850   PetscFunctionBegin;
851   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
852   if (!((PetscObject)A)->type_name) {
853     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
854     if (size == 1) {
855       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
856     } else {
857       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
858     }
859   }
860   if (!A->preallocated && A->ops->setup) {
861     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
862     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
863   }
864   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
865   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
866   A->preallocated = PETSC_TRUE;
867   PetscFunctionReturn(0);
868 }
869 
870 #if defined(PETSC_HAVE_SAWS)
871 #include <petscviewersaws.h>
872 #endif
873 /*@C
874    MatView - Visualizes a matrix object.
875 
876    Collective on Mat
877 
878    Input Parameters:
879 +  mat - the matrix
880 -  viewer - visualization context
881 
882   Notes:
883   The available visualization contexts include
884 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
885 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
886 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
887 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
888 
889    The user can open alternative visualization contexts with
890 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
891 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
892          specified file; corresponding input uses MatLoad()
893 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
894          an X window display
895 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
896          Currently only the sequential dense and AIJ
897          matrix types support the Socket viewer.
898 
899    The user can call PetscViewerPushFormat() to specify the output
900    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
901    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
902 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
903 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
904 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
905 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
906          format common among all matrix types
907 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
908          format (which is in many cases the same as the default)
909 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
910          size and structure (not the matrix entries)
911 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
912          the matrix structure
913 
914    Options Database Keys:
915 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
916 .  -mat_view ::ascii_info_detail - Prints more detailed info
917 .  -mat_view - Prints matrix in ASCII format
918 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
919 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
920 .  -display <name> - Sets display name (default is host)
921 .  -draw_pause <sec> - Sets number of seconds to pause after display
922 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
923 .  -viewer_socket_machine <machine> -
924 .  -viewer_socket_port <port> -
925 .  -mat_view binary - save matrix to file in binary format
926 -  -viewer_binary_filename <name> -
927    Level: beginner
928 
929    Notes:
930     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
931     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
932 
933     See the manual page for MatLoad() for the exact format of the binary file when the binary
934       viewer is used.
935 
936       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
937       viewer is used.
938 
939       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
940       and then use the following mouse functions.
941 + left mouse: zoom in
942 . middle mouse: zoom out
943 - right mouse: continue with the simulation
944 
945 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
946           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
947 @*/
948 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
949 {
950   PetscErrorCode    ierr;
951   PetscInt          rows,cols,rbs,cbs;
952   PetscBool         iascii,ibinary,isstring;
953   PetscViewerFormat format;
954   PetscMPIInt       size;
955 #if defined(PETSC_HAVE_SAWS)
956   PetscBool         issaws;
957 #endif
958 
959   PetscFunctionBegin;
960   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
961   PetscValidType(mat,1);
962   if (!viewer) {
963     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
964   }
965   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
966   PetscCheckSameComm(mat,1,viewer,2);
967   MatCheckPreallocated(mat,1);
968   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
969   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
970   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
971   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
972   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
973   if (ibinary) {
974     PetscBool mpiio;
975     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
976     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
977   }
978 
979   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
980   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
981   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
982     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
983   }
984 
985 #if defined(PETSC_HAVE_SAWS)
986   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
987 #endif
988   if (iascii) {
989     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
990     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
991     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
992       MatNullSpace nullsp,transnullsp;
993 
994       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
995       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
996       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
997       if (rbs != 1 || cbs != 1) {
998         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
999         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1000       } else {
1001         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1002       }
1003       if (mat->factortype) {
1004         MatSolverType solver;
1005         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1006         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1007       }
1008       if (mat->ops->getinfo) {
1009         MatInfo info;
1010         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1011         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1012         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1013       }
1014       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1015       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1016       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1017       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1018       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1019       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1020     }
1021 #if defined(PETSC_HAVE_SAWS)
1022   } else if (issaws) {
1023     PetscMPIInt rank;
1024 
1025     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1026     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1027     if (!((PetscObject)mat)->amsmem && !rank) {
1028       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1029     }
1030 #endif
1031   } else if (isstring) {
1032     const char *type;
1033     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1034     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1035     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1036   }
1037   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1038     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1039     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1040     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1041   } else if (mat->ops->view) {
1042     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1043     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1044     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1045   }
1046   if (iascii) {
1047     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1048     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1049       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1050     }
1051   }
1052   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1053   PetscFunctionReturn(0);
1054 }
1055 
1056 #if defined(PETSC_USE_DEBUG)
1057 #include <../src/sys/totalview/tv_data_display.h>
1058 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1059 {
1060   TV_add_row("Local rows", "int", &mat->rmap->n);
1061   TV_add_row("Local columns", "int", &mat->cmap->n);
1062   TV_add_row("Global rows", "int", &mat->rmap->N);
1063   TV_add_row("Global columns", "int", &mat->cmap->N);
1064   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1065   return TV_format_OK;
1066 }
1067 #endif
1068 
1069 /*@C
1070    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1071    with MatView().  The matrix format is determined from the options database.
1072    Generates a parallel MPI matrix if the communicator has more than one
1073    processor.  The default matrix type is AIJ.
1074 
1075    Collective on PetscViewer
1076 
1077    Input Parameters:
1078 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1079             or some related function before a call to MatLoad()
1080 -  viewer - binary/HDF5 file viewer
1081 
1082    Options Database Keys:
1083    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1084    block size
1085 .    -matload_block_size <bs>
1086 
1087    Level: beginner
1088 
1089    Notes:
1090    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1091    Mat before calling this routine if you wish to set it from the options database.
1092 
1093    MatLoad() automatically loads into the options database any options
1094    given in the file filename.info where filename is the name of the file
1095    that was passed to the PetscViewerBinaryOpen(). The options in the info
1096    file will be ignored if you use the -viewer_binary_skip_info option.
1097 
1098    If the type or size of newmat is not set before a call to MatLoad, PETSc
1099    sets the default matrix type AIJ and sets the local and global sizes.
1100    If type and/or size is already set, then the same are used.
1101 
1102    In parallel, each processor can load a subset of rows (or the
1103    entire matrix).  This routine is especially useful when a large
1104    matrix is stored on disk and only part of it is desired on each
1105    processor.  For example, a parallel solver may access only some of
1106    the rows from each processor.  The algorithm used here reads
1107    relatively small blocks of data rather than reading the entire
1108    matrix and then subsetting it.
1109 
1110    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1111    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1112    or the sequence like
1113 $    PetscViewer v;
1114 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1115 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1116 $    PetscViewerSetFromOptions(v);
1117 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1118 $    PetscViewerFileSetName(v,"datafile");
1119    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1120 $ -viewer_type {binary,hdf5}
1121 
1122    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1123    and src/mat/examples/tutorials/ex10.c with the second approach.
1124 
1125    Notes about the PETSc binary format:
1126    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1127    is read onto rank 0 and then shipped to its destination rank, one after another.
1128    Multiple objects, both matrices and vectors, can be stored within the same file.
1129    Their PetscObject name is ignored; they are loaded in the order of their storage.
1130 
1131    Most users should not need to know the details of the binary storage
1132    format, since MatLoad() and MatView() completely hide these details.
1133    But for anyone who's interested, the standard binary matrix storage
1134    format is
1135 
1136 $    PetscInt    MAT_FILE_CLASSID
1137 $    PetscInt    number of rows
1138 $    PetscInt    number of columns
1139 $    PetscInt    total number of nonzeros
1140 $    PetscInt    *number nonzeros in each row
1141 $    PetscInt    *column indices of all nonzeros (starting index is zero)
1142 $    PetscScalar *values of all nonzeros
1143 
1144    PETSc automatically does the byte swapping for
1145 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1146 linux, Windows and the paragon; thus if you write your own binary
1147 read/write routines you have to swap the bytes; see PetscBinaryRead()
1148 and PetscBinaryWrite() to see how this may be done.
1149 
1150    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1151    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1152    Each processor's chunk is loaded independently by its owning rank.
1153    Multiple objects, both matrices and vectors, can be stored within the same file.
1154    They are looked up by their PetscObject name.
1155 
1156    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1157    by default the same structure and naming of the AIJ arrays and column count
1158    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1159 $    save example.mat A b -v7.3
1160    can be directly read by this routine (see Reference 1 for details).
1161    Note that depending on your MATLAB version, this format might be a default,
1162    otherwise you can set it as default in Preferences.
1163 
1164    Unless -nocompression flag is used to save the file in MATLAB,
1165    PETSc must be configured with ZLIB package.
1166 
1167    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1168 
1169    Current HDF5 (MAT-File) limitations:
1170    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1171 
1172    Corresponding MatView() is not yet implemented.
1173 
1174    The loaded matrix is actually a transpose of the original one in MATLAB,
1175    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1176    With this format, matrix is automatically transposed by PETSc,
1177    unless the matrix is marked as SPD or symmetric
1178    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1179 
1180    References:
1181 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1182 
1183 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1184 
1185  @*/
1186 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1187 {
1188   PetscErrorCode ierr;
1189   PetscBool      flg;
1190 
1191   PetscFunctionBegin;
1192   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1193   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1194 
1195   if (!((PetscObject)newmat)->type_name) {
1196     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1197   }
1198 
1199   flg  = PETSC_FALSE;
1200   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1201   if (flg) {
1202     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1203     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1204   }
1205   flg  = PETSC_FALSE;
1206   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1207   if (flg) {
1208     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1209   }
1210 
1211   if (!newmat->ops->load) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)newmat)->type_name);
1212   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1213   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1214   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1215   PetscFunctionReturn(0);
1216 }
1217 
1218 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1219 {
1220   PetscErrorCode ierr;
1221   Mat_Redundant  *redund = *redundant;
1222   PetscInt       i;
1223 
1224   PetscFunctionBegin;
1225   if (redund){
1226     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1227       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1228       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1229       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1230     } else {
1231       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1232       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1233       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1234       for (i=0; i<redund->nrecvs; i++) {
1235         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1236         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1237       }
1238       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1239     }
1240 
1241     if (redund->subcomm) {
1242       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1243     }
1244     ierr = PetscFree(redund);CHKERRQ(ierr);
1245   }
1246   PetscFunctionReturn(0);
1247 }
1248 
1249 /*@
1250    MatDestroy - Frees space taken by a matrix.
1251 
1252    Collective on Mat
1253 
1254    Input Parameter:
1255 .  A - the matrix
1256 
1257    Level: beginner
1258 
1259 @*/
1260 PetscErrorCode MatDestroy(Mat *A)
1261 {
1262   PetscErrorCode ierr;
1263 
1264   PetscFunctionBegin;
1265   if (!*A) PetscFunctionReturn(0);
1266   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1267   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1268 
1269   /* if memory was published with SAWs then destroy it */
1270   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1271   if ((*A)->ops->destroy) {
1272     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1273   }
1274 
1275   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1276   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1277   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1278   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1279   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1280   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1281   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1282   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1283   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1284   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1285   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1286   PetscFunctionReturn(0);
1287 }
1288 
1289 /*@C
1290    MatSetValues - Inserts or adds a block of values into a matrix.
1291    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1292    MUST be called after all calls to MatSetValues() have been completed.
1293 
1294    Not Collective
1295 
1296    Input Parameters:
1297 +  mat - the matrix
1298 .  v - a logically two-dimensional array of values
1299 .  m, idxm - the number of rows and their global indices
1300 .  n, idxn - the number of columns and their global indices
1301 -  addv - either ADD_VALUES or INSERT_VALUES, where
1302    ADD_VALUES adds values to any existing entries, and
1303    INSERT_VALUES replaces existing entries with new values
1304 
1305    Notes:
1306    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1307       MatSetUp() before using this routine
1308 
1309    By default the values, v, are row-oriented. See MatSetOption() for other options.
1310 
1311    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1312    options cannot be mixed without intervening calls to the assembly
1313    routines.
1314 
1315    MatSetValues() uses 0-based row and column numbers in Fortran
1316    as well as in C.
1317 
1318    Negative indices may be passed in idxm and idxn, these rows and columns are
1319    simply ignored. This allows easily inserting element stiffness matrices
1320    with homogeneous Dirchlet boundary conditions that you don't want represented
1321    in the matrix.
1322 
1323    Efficiency Alert:
1324    The routine MatSetValuesBlocked() may offer much better efficiency
1325    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1326 
1327    Level: beginner
1328 
1329    Developer Notes:
1330     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1331                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1332 
1333 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1334           InsertMode, INSERT_VALUES, ADD_VALUES
1335 @*/
1336 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1337 {
1338   PetscErrorCode ierr;
1339 #if defined(PETSC_USE_DEBUG)
1340   PetscInt       i,j;
1341 #endif
1342 
1343   PetscFunctionBeginHot;
1344   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1345   PetscValidType(mat,1);
1346   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1347   PetscValidIntPointer(idxm,3);
1348   PetscValidIntPointer(idxn,5);
1349   MatCheckPreallocated(mat,1);
1350 
1351   if (mat->insertmode == NOT_SET_VALUES) {
1352     mat->insertmode = addv;
1353   }
1354 #if defined(PETSC_USE_DEBUG)
1355   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1356   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1357   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1358 
1359   for (i=0; i<m; i++) {
1360     for (j=0; j<n; j++) {
1361       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1362 #if defined(PETSC_USE_COMPLEX)
1363         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]);
1364 #else
1365         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1366 #endif
1367     }
1368   }
1369 #endif
1370 
1371   if (mat->assembled) {
1372     mat->was_assembled = PETSC_TRUE;
1373     mat->assembled     = PETSC_FALSE;
1374   }
1375   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1376   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1377   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1378   PetscFunctionReturn(0);
1379 }
1380 
1381 
1382 /*@
1383    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1384         values into a matrix
1385 
1386    Not Collective
1387 
1388    Input Parameters:
1389 +  mat - the matrix
1390 .  row - the (block) row to set
1391 -  v - a logically two-dimensional array of values
1392 
1393    Notes:
1394    By the values, v, are column-oriented (for the block version) and sorted
1395 
1396    All the nonzeros in the row must be provided
1397 
1398    The matrix must have previously had its column indices set
1399 
1400    The row must belong to this process
1401 
1402    Level: intermediate
1403 
1404 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1405           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1406 @*/
1407 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1408 {
1409   PetscErrorCode ierr;
1410   PetscInt       globalrow;
1411 
1412   PetscFunctionBegin;
1413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1414   PetscValidType(mat,1);
1415   PetscValidScalarPointer(v,2);
1416   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1417   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1418   PetscFunctionReturn(0);
1419 }
1420 
1421 /*@
1422    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1423         values into a matrix
1424 
1425    Not Collective
1426 
1427    Input Parameters:
1428 +  mat - the matrix
1429 .  row - the (block) row to set
1430 -  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
1431 
1432    Notes:
1433    The values, v, are column-oriented for the block version.
1434 
1435    All the nonzeros in the row must be provided
1436 
1437    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1438 
1439    The row must belong to this process
1440 
1441    Level: advanced
1442 
1443 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1444           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1445 @*/
1446 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1447 {
1448   PetscErrorCode ierr;
1449 
1450   PetscFunctionBeginHot;
1451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1452   PetscValidType(mat,1);
1453   MatCheckPreallocated(mat,1);
1454   PetscValidScalarPointer(v,2);
1455 #if defined(PETSC_USE_DEBUG)
1456   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1457   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1458 #endif
1459   mat->insertmode = INSERT_VALUES;
1460 
1461   if (mat->assembled) {
1462     mat->was_assembled = PETSC_TRUE;
1463     mat->assembled     = PETSC_FALSE;
1464   }
1465   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1466   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1467   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1468   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1469   PetscFunctionReturn(0);
1470 }
1471 
1472 /*@
1473    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1474      Using structured grid indexing
1475 
1476    Not Collective
1477 
1478    Input Parameters:
1479 +  mat - the matrix
1480 .  m - number of rows being entered
1481 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1482 .  n - number of columns being entered
1483 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1484 .  v - a logically two-dimensional array of values
1485 -  addv - either ADD_VALUES or INSERT_VALUES, where
1486    ADD_VALUES adds values to any existing entries, and
1487    INSERT_VALUES replaces existing entries with new values
1488 
1489    Notes:
1490    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1491 
1492    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1493    options cannot be mixed without intervening calls to the assembly
1494    routines.
1495 
1496    The grid coordinates are across the entire grid, not just the local portion
1497 
1498    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1499    as well as in C.
1500 
1501    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1502 
1503    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1504    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1505 
1506    The columns and rows in the stencil passed in MUST be contained within the
1507    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1508    if you create a DMDA with an overlap of one grid level and on a particular process its first
1509    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1510    first i index you can use in your column and row indices in MatSetStencil() is 5.
1511 
1512    In Fortran idxm and idxn should be declared as
1513 $     MatStencil idxm(4,m),idxn(4,n)
1514    and the values inserted using
1515 $    idxm(MatStencil_i,1) = i
1516 $    idxm(MatStencil_j,1) = j
1517 $    idxm(MatStencil_k,1) = k
1518 $    idxm(MatStencil_c,1) = c
1519    etc
1520 
1521    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1522    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1523    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1524    DM_BOUNDARY_PERIODIC boundary type.
1525 
1526    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
1527    a single value per point) you can skip filling those indices.
1528 
1529    Inspired by the structured grid interface to the HYPRE package
1530    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1531 
1532    Efficiency Alert:
1533    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1534    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1535 
1536    Level: beginner
1537 
1538 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1539           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1540 @*/
1541 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1542 {
1543   PetscErrorCode ierr;
1544   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1545   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1546   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1547 
1548   PetscFunctionBegin;
1549   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1550   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1551   PetscValidType(mat,1);
1552   PetscValidIntPointer(idxm,3);
1553   PetscValidIntPointer(idxn,5);
1554 
1555   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1556     jdxm = buf; jdxn = buf+m;
1557   } else {
1558     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1559     jdxm = bufm; jdxn = bufn;
1560   }
1561   for (i=0; i<m; i++) {
1562     for (j=0; j<3-sdim; j++) dxm++;
1563     tmp = *dxm++ - starts[0];
1564     for (j=0; j<dim-1; j++) {
1565       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1566       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1567     }
1568     if (mat->stencil.noc) dxm++;
1569     jdxm[i] = tmp;
1570   }
1571   for (i=0; i<n; i++) {
1572     for (j=0; j<3-sdim; j++) dxn++;
1573     tmp = *dxn++ - starts[0];
1574     for (j=0; j<dim-1; j++) {
1575       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1576       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1577     }
1578     if (mat->stencil.noc) dxn++;
1579     jdxn[i] = tmp;
1580   }
1581   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1582   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1583   PetscFunctionReturn(0);
1584 }
1585 
1586 /*@
1587    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1588      Using structured grid indexing
1589 
1590    Not Collective
1591 
1592    Input Parameters:
1593 +  mat - the matrix
1594 .  m - number of rows being entered
1595 .  idxm - grid coordinates for matrix rows being entered
1596 .  n - number of columns being entered
1597 .  idxn - grid coordinates for matrix columns being entered
1598 .  v - a logically two-dimensional array of values
1599 -  addv - either ADD_VALUES or INSERT_VALUES, where
1600    ADD_VALUES adds values to any existing entries, and
1601    INSERT_VALUES replaces existing entries with new values
1602 
1603    Notes:
1604    By default the values, v, are row-oriented and unsorted.
1605    See MatSetOption() for other options.
1606 
1607    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1608    options cannot be mixed without intervening calls to the assembly
1609    routines.
1610 
1611    The grid coordinates are across the entire grid, not just the local portion
1612 
1613    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1614    as well as in C.
1615 
1616    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1617 
1618    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1619    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1620 
1621    The columns and rows in the stencil passed in MUST be contained within the
1622    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1623    if you create a DMDA with an overlap of one grid level and on a particular process its first
1624    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1625    first i index you can use in your column and row indices in MatSetStencil() is 5.
1626 
1627    In Fortran idxm and idxn should be declared as
1628 $     MatStencil idxm(4,m),idxn(4,n)
1629    and the values inserted using
1630 $    idxm(MatStencil_i,1) = i
1631 $    idxm(MatStencil_j,1) = j
1632 $    idxm(MatStencil_k,1) = k
1633    etc
1634 
1635    Negative indices may be passed in idxm and idxn, these rows and columns are
1636    simply ignored. This allows easily inserting element stiffness matrices
1637    with homogeneous Dirchlet boundary conditions that you don't want represented
1638    in the matrix.
1639 
1640    Inspired by the structured grid interface to the HYPRE package
1641    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1642 
1643    Level: beginner
1644 
1645 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1646           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1647           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1648 @*/
1649 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1650 {
1651   PetscErrorCode ierr;
1652   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1653   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1654   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1655 
1656   PetscFunctionBegin;
1657   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1659   PetscValidType(mat,1);
1660   PetscValidIntPointer(idxm,3);
1661   PetscValidIntPointer(idxn,5);
1662   PetscValidScalarPointer(v,6);
1663 
1664   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1665     jdxm = buf; jdxn = buf+m;
1666   } else {
1667     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1668     jdxm = bufm; jdxn = bufn;
1669   }
1670   for (i=0; i<m; i++) {
1671     for (j=0; j<3-sdim; j++) dxm++;
1672     tmp = *dxm++ - starts[0];
1673     for (j=0; j<sdim-1; j++) {
1674       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1675       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1676     }
1677     dxm++;
1678     jdxm[i] = tmp;
1679   }
1680   for (i=0; i<n; i++) {
1681     for (j=0; j<3-sdim; j++) dxn++;
1682     tmp = *dxn++ - starts[0];
1683     for (j=0; j<sdim-1; j++) {
1684       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1685       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1686     }
1687     dxn++;
1688     jdxn[i] = tmp;
1689   }
1690   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1691   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1692   PetscFunctionReturn(0);
1693 }
1694 
1695 /*@
1696    MatSetStencil - Sets the grid information for setting values into a matrix via
1697         MatSetValuesStencil()
1698 
1699    Not Collective
1700 
1701    Input Parameters:
1702 +  mat - the matrix
1703 .  dim - dimension of the grid 1, 2, or 3
1704 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1705 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1706 -  dof - number of degrees of freedom per node
1707 
1708 
1709    Inspired by the structured grid interface to the HYPRE package
1710    (www.llnl.gov/CASC/hyper)
1711 
1712    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1713    user.
1714 
1715    Level: beginner
1716 
1717 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1718           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1719 @*/
1720 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1721 {
1722   PetscInt i;
1723 
1724   PetscFunctionBegin;
1725   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1726   PetscValidIntPointer(dims,3);
1727   PetscValidIntPointer(starts,4);
1728 
1729   mat->stencil.dim = dim + (dof > 1);
1730   for (i=0; i<dim; i++) {
1731     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1732     mat->stencil.starts[i] = starts[dim-i-1];
1733   }
1734   mat->stencil.dims[dim]   = dof;
1735   mat->stencil.starts[dim] = 0;
1736   mat->stencil.noc         = (PetscBool)(dof == 1);
1737   PetscFunctionReturn(0);
1738 }
1739 
1740 /*@C
1741    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1742 
1743    Not Collective
1744 
1745    Input Parameters:
1746 +  mat - the matrix
1747 .  v - a logically two-dimensional array of values
1748 .  m, idxm - the number of block rows and their global block indices
1749 .  n, idxn - the number of block columns and their global block indices
1750 -  addv - either ADD_VALUES or INSERT_VALUES, where
1751    ADD_VALUES adds values to any existing entries, and
1752    INSERT_VALUES replaces existing entries with new values
1753 
1754    Notes:
1755    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1756    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1757 
1758    The m and n count the NUMBER of blocks in the row direction and column direction,
1759    NOT the total number of rows/columns; for example, if the block size is 2 and
1760    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1761    The values in idxm would be 1 2; that is the first index for each block divided by
1762    the block size.
1763 
1764    Note that you must call MatSetBlockSize() when constructing this matrix (before
1765    preallocating it).
1766 
1767    By default the values, v, are row-oriented, so the layout of
1768    v is the same as for MatSetValues(). See MatSetOption() for other options.
1769 
1770    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1771    options cannot be mixed without intervening calls to the assembly
1772    routines.
1773 
1774    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1775    as well as in C.
1776 
1777    Negative indices may be passed in idxm and idxn, these rows and columns are
1778    simply ignored. This allows easily inserting element stiffness matrices
1779    with homogeneous Dirchlet boundary conditions that you don't want represented
1780    in the matrix.
1781 
1782    Each time an entry is set within a sparse matrix via MatSetValues(),
1783    internal searching must be done to determine where to place the
1784    data in the matrix storage space.  By instead inserting blocks of
1785    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1786    reduced.
1787 
1788    Example:
1789 $   Suppose m=n=2 and block size(bs) = 2 The array is
1790 $
1791 $   1  2  | 3  4
1792 $   5  6  | 7  8
1793 $   - - - | - - -
1794 $   9  10 | 11 12
1795 $   13 14 | 15 16
1796 $
1797 $   v[] should be passed in like
1798 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1799 $
1800 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1801 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1802 
1803    Level: intermediate
1804 
1805 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1806 @*/
1807 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1808 {
1809   PetscErrorCode ierr;
1810 
1811   PetscFunctionBeginHot;
1812   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1813   PetscValidType(mat,1);
1814   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1815   PetscValidIntPointer(idxm,3);
1816   PetscValidIntPointer(idxn,5);
1817   PetscValidScalarPointer(v,6);
1818   MatCheckPreallocated(mat,1);
1819   if (mat->insertmode == NOT_SET_VALUES) {
1820     mat->insertmode = addv;
1821   }
1822 #if defined(PETSC_USE_DEBUG)
1823   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1824   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1825   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1826 #endif
1827 
1828   if (mat->assembled) {
1829     mat->was_assembled = PETSC_TRUE;
1830     mat->assembled     = PETSC_FALSE;
1831   }
1832   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1833   if (mat->ops->setvaluesblocked) {
1834     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1835   } else {
1836     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1837     PetscInt i,j,bs,cbs;
1838     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1839     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1840       iidxm = buf; iidxn = buf + m*bs;
1841     } else {
1842       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1843       iidxm = bufr; iidxn = bufc;
1844     }
1845     for (i=0; i<m; i++) {
1846       for (j=0; j<bs; j++) {
1847         iidxm[i*bs+j] = bs*idxm[i] + j;
1848       }
1849     }
1850     for (i=0; i<n; i++) {
1851       for (j=0; j<cbs; j++) {
1852         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1853       }
1854     }
1855     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1856     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1857   }
1858   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1859   PetscFunctionReturn(0);
1860 }
1861 
1862 /*@
1863    MatGetValues - Gets a block of values from a matrix.
1864 
1865    Not Collective; currently only returns a local block
1866 
1867    Input Parameters:
1868 +  mat - the matrix
1869 .  v - a logically two-dimensional array for storing the values
1870 .  m, idxm - the number of rows and their global indices
1871 -  n, idxn - the number of columns and their global indices
1872 
1873    Notes:
1874    The user must allocate space (m*n PetscScalars) for the values, v.
1875    The values, v, are then returned in a row-oriented format,
1876    analogous to that used by default in MatSetValues().
1877 
1878    MatGetValues() uses 0-based row and column numbers in
1879    Fortran as well as in C.
1880 
1881    MatGetValues() requires that the matrix has been assembled
1882    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1883    MatSetValues() and MatGetValues() CANNOT be made in succession
1884    without intermediate matrix assembly.
1885 
1886    Negative row or column indices will be ignored and those locations in v[] will be
1887    left unchanged.
1888 
1889    Level: advanced
1890 
1891 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1892 @*/
1893 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1894 {
1895   PetscErrorCode ierr;
1896 
1897   PetscFunctionBegin;
1898   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1899   PetscValidType(mat,1);
1900   if (!m || !n) PetscFunctionReturn(0);
1901   PetscValidIntPointer(idxm,3);
1902   PetscValidIntPointer(idxn,5);
1903   PetscValidScalarPointer(v,6);
1904   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1905   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1906   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1907   MatCheckPreallocated(mat,1);
1908 
1909   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1910   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1911   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1912   PetscFunctionReturn(0);
1913 }
1914 
1915 /*@
1916   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1917   the same size. Currently, this can only be called once and creates the given matrix.
1918 
1919   Not Collective
1920 
1921   Input Parameters:
1922 + mat - the matrix
1923 . nb - the number of blocks
1924 . bs - the number of rows (and columns) in each block
1925 . rows - a concatenation of the rows for each block
1926 - v - a concatenation of logically two-dimensional arrays of values
1927 
1928   Notes:
1929   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1930 
1931   Level: advanced
1932 
1933 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1934           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1935 @*/
1936 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1937 {
1938   PetscErrorCode ierr;
1939 
1940   PetscFunctionBegin;
1941   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1942   PetscValidType(mat,1);
1943   PetscValidScalarPointer(rows,4);
1944   PetscValidScalarPointer(v,5);
1945 #if defined(PETSC_USE_DEBUG)
1946   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1947 #endif
1948 
1949   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1950   if (mat->ops->setvaluesbatch) {
1951     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1952   } else {
1953     PetscInt b;
1954     for (b = 0; b < nb; ++b) {
1955       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1956     }
1957   }
1958   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1959   PetscFunctionReturn(0);
1960 }
1961 
1962 /*@
1963    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1964    the routine MatSetValuesLocal() to allow users to insert matrix entries
1965    using a local (per-processor) numbering.
1966 
1967    Not Collective
1968 
1969    Input Parameters:
1970 +  x - the matrix
1971 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1972 - cmapping - column mapping
1973 
1974    Level: intermediate
1975 
1976 
1977 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1978 @*/
1979 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1980 {
1981   PetscErrorCode ierr;
1982 
1983   PetscFunctionBegin;
1984   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
1985   PetscValidType(x,1);
1986   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
1987   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
1988 
1989   if (x->ops->setlocaltoglobalmapping) {
1990     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
1991   } else {
1992     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
1993     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
1994   }
1995   PetscFunctionReturn(0);
1996 }
1997 
1998 
1999 /*@
2000    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2001 
2002    Not Collective
2003 
2004    Input Parameters:
2005 .  A - the matrix
2006 
2007    Output Parameters:
2008 + rmapping - row mapping
2009 - cmapping - column mapping
2010 
2011    Level: advanced
2012 
2013 
2014 .seealso:  MatSetValuesLocal()
2015 @*/
2016 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2017 {
2018   PetscFunctionBegin;
2019   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2020   PetscValidType(A,1);
2021   if (rmapping) PetscValidPointer(rmapping,2);
2022   if (cmapping) PetscValidPointer(cmapping,3);
2023   if (rmapping) *rmapping = A->rmap->mapping;
2024   if (cmapping) *cmapping = A->cmap->mapping;
2025   PetscFunctionReturn(0);
2026 }
2027 
2028 /*@
2029    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2030 
2031    Not Collective
2032 
2033    Input Parameters:
2034 .  A - the matrix
2035 
2036    Output Parameters:
2037 + rmap - row layout
2038 - cmap - column layout
2039 
2040    Level: advanced
2041 
2042 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2043 @*/
2044 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2045 {
2046   PetscFunctionBegin;
2047   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2048   PetscValidType(A,1);
2049   if (rmap) PetscValidPointer(rmap,2);
2050   if (cmap) PetscValidPointer(cmap,3);
2051   if (rmap) *rmap = A->rmap;
2052   if (cmap) *cmap = A->cmap;
2053   PetscFunctionReturn(0);
2054 }
2055 
2056 /*@C
2057    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2058    using a local ordering of the nodes.
2059 
2060    Not Collective
2061 
2062    Input Parameters:
2063 +  mat - the matrix
2064 .  nrow, irow - number of rows and their local indices
2065 .  ncol, icol - number of columns and their local indices
2066 .  y -  a logically two-dimensional array of values
2067 -  addv - either INSERT_VALUES or ADD_VALUES, where
2068    ADD_VALUES adds values to any existing entries, and
2069    INSERT_VALUES replaces existing entries with new values
2070 
2071    Notes:
2072    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2073       MatSetUp() before using this routine
2074 
2075    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2076 
2077    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2078    options cannot be mixed without intervening calls to the assembly
2079    routines.
2080 
2081    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2082    MUST be called after all calls to MatSetValuesLocal() have been completed.
2083 
2084    Level: intermediate
2085 
2086    Developer Notes:
2087     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2088                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2089 
2090 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2091            MatSetValueLocal()
2092 @*/
2093 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2094 {
2095   PetscErrorCode ierr;
2096 
2097   PetscFunctionBeginHot;
2098   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2099   PetscValidType(mat,1);
2100   MatCheckPreallocated(mat,1);
2101   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2102   PetscValidIntPointer(irow,3);
2103   PetscValidIntPointer(icol,5);
2104   if (mat->insertmode == NOT_SET_VALUES) {
2105     mat->insertmode = addv;
2106   }
2107 #if defined(PETSC_USE_DEBUG)
2108   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2109   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2110   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2111 #endif
2112 
2113   if (mat->assembled) {
2114     mat->was_assembled = PETSC_TRUE;
2115     mat->assembled     = PETSC_FALSE;
2116   }
2117   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2118   if (mat->ops->setvalueslocal) {
2119     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2120   } else {
2121     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2122     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2123       irowm = buf; icolm = buf+nrow;
2124     } else {
2125       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2126       irowm = bufr; icolm = bufc;
2127     }
2128     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2129     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2130     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2131     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2132     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2133     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2134   }
2135   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2136   PetscFunctionReturn(0);
2137 }
2138 
2139 /*@C
2140    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2141    using a local ordering of the nodes a block at a time.
2142 
2143    Not Collective
2144 
2145    Input Parameters:
2146 +  x - the matrix
2147 .  nrow, irow - number of rows and their local indices
2148 .  ncol, icol - number of columns and their local indices
2149 .  y -  a logically two-dimensional array of values
2150 -  addv - either INSERT_VALUES or ADD_VALUES, where
2151    ADD_VALUES adds values to any existing entries, and
2152    INSERT_VALUES replaces existing entries with new values
2153 
2154    Notes:
2155    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2156       MatSetUp() before using this routine
2157 
2158    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2159       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2160 
2161    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2162    options cannot be mixed without intervening calls to the assembly
2163    routines.
2164 
2165    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2166    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2167 
2168    Level: intermediate
2169 
2170    Developer Notes:
2171     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2172                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2173 
2174 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2175            MatSetValuesLocal(),  MatSetValuesBlocked()
2176 @*/
2177 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2178 {
2179   PetscErrorCode ierr;
2180 
2181   PetscFunctionBeginHot;
2182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2183   PetscValidType(mat,1);
2184   MatCheckPreallocated(mat,1);
2185   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2186   PetscValidIntPointer(irow,3);
2187   PetscValidIntPointer(icol,5);
2188   PetscValidScalarPointer(y,6);
2189   if (mat->insertmode == NOT_SET_VALUES) {
2190     mat->insertmode = addv;
2191   }
2192 #if defined(PETSC_USE_DEBUG)
2193   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2194   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2195   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);
2196 #endif
2197 
2198   if (mat->assembled) {
2199     mat->was_assembled = PETSC_TRUE;
2200     mat->assembled     = PETSC_FALSE;
2201   }
2202 #if defined(PETSC_USE_DEBUG)
2203   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2204   if (mat->rmap->mapping) {
2205     PetscInt irbs, rbs;
2206     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2207     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2208     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2209   }
2210   if (mat->cmap->mapping) {
2211     PetscInt icbs, cbs;
2212     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2213     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2214     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2215   }
2216 #endif
2217   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2218   if (mat->ops->setvaluesblockedlocal) {
2219     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2220   } else {
2221     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2222     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2223       irowm = buf; icolm = buf + nrow;
2224     } else {
2225       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2226       irowm = bufr; icolm = bufc;
2227     }
2228     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2229     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2230     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2231     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2232   }
2233   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2234   PetscFunctionReturn(0);
2235 }
2236 
2237 /*@
2238    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2239 
2240    Collective on Mat
2241 
2242    Input Parameters:
2243 +  mat - the matrix
2244 -  x   - the vector to be multiplied
2245 
2246    Output Parameters:
2247 .  y - the result
2248 
2249    Notes:
2250    The vectors x and y cannot be the same.  I.e., one cannot
2251    call MatMult(A,y,y).
2252 
2253    Level: developer
2254 
2255 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2256 @*/
2257 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2258 {
2259   PetscErrorCode ierr;
2260 
2261   PetscFunctionBegin;
2262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2263   PetscValidType(mat,1);
2264   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2265   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2266 
2267   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2268   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2269   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2270   MatCheckPreallocated(mat,1);
2271 
2272   if (!mat->ops->multdiagonalblock) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2273   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2274   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2275   PetscFunctionReturn(0);
2276 }
2277 
2278 /* --------------------------------------------------------*/
2279 /*@
2280    MatMult - Computes the matrix-vector product, y = Ax.
2281 
2282    Neighbor-wise Collective on Mat
2283 
2284    Input Parameters:
2285 +  mat - the matrix
2286 -  x   - the vector to be multiplied
2287 
2288    Output Parameters:
2289 .  y - the result
2290 
2291    Notes:
2292    The vectors x and y cannot be the same.  I.e., one cannot
2293    call MatMult(A,y,y).
2294 
2295    Level: beginner
2296 
2297 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2298 @*/
2299 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2300 {
2301   PetscErrorCode ierr;
2302 
2303   PetscFunctionBegin;
2304   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2305   PetscValidType(mat,1);
2306   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2307   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2308   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2309   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2310   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2311 #if !defined(PETSC_HAVE_CONSTRAINTS)
2312   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);
2313   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);
2314   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);
2315 #endif
2316   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2317   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2318   MatCheckPreallocated(mat,1);
2319 
2320   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2321   if (!mat->ops->mult) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2322   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2323   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2324   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2325   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2326   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2327   PetscFunctionReturn(0);
2328 }
2329 
2330 /*@
2331    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2332 
2333    Neighbor-wise Collective on Mat
2334 
2335    Input Parameters:
2336 +  mat - the matrix
2337 -  x   - the vector to be multiplied
2338 
2339    Output Parameters:
2340 .  y - the result
2341 
2342    Notes:
2343    The vectors x and y cannot be the same.  I.e., one cannot
2344    call MatMultTranspose(A,y,y).
2345 
2346    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2347    use MatMultHermitianTranspose()
2348 
2349    Level: beginner
2350 
2351 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2352 @*/
2353 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2354 {
2355   PetscErrorCode ierr;
2356 
2357   PetscFunctionBegin;
2358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2359   PetscValidType(mat,1);
2360   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2361   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2362 
2363   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2364   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2365   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2366 #if !defined(PETSC_HAVE_CONSTRAINTS)
2367   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);
2368   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);
2369 #endif
2370   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2371   MatCheckPreallocated(mat,1);
2372 
2373   if (!mat->ops->multtranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined",((PetscObject)mat)->type_name);
2374   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2375   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2376   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2377   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2378   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2379   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2380   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2381   PetscFunctionReturn(0);
2382 }
2383 
2384 /*@
2385    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2386 
2387    Neighbor-wise Collective on Mat
2388 
2389    Input Parameters:
2390 +  mat - the matrix
2391 -  x   - the vector to be multilplied
2392 
2393    Output Parameters:
2394 .  y - the result
2395 
2396    Notes:
2397    The vectors x and y cannot be the same.  I.e., one cannot
2398    call MatMultHermitianTranspose(A,y,y).
2399 
2400    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2401 
2402    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2403 
2404    Level: beginner
2405 
2406 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2407 @*/
2408 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2409 {
2410   PetscErrorCode ierr;
2411   Vec            w;
2412 
2413   PetscFunctionBegin;
2414   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2415   PetscValidType(mat,1);
2416   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2417   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2418 
2419   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2420   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2421   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2422 #if !defined(PETSC_HAVE_CONSTRAINTS)
2423   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);
2424   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);
2425 #endif
2426   MatCheckPreallocated(mat,1);
2427 
2428   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2429   if (mat->ops->multhermitiantranspose) {
2430     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2431     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2432     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2433   } else {
2434     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2435     ierr = VecCopy(x,w);CHKERRQ(ierr);
2436     ierr = VecConjugate(w);CHKERRQ(ierr);
2437     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2438     ierr = VecDestroy(&w);CHKERRQ(ierr);
2439     ierr = VecConjugate(y);CHKERRQ(ierr);
2440   }
2441   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2442   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2443   PetscFunctionReturn(0);
2444 }
2445 
2446 /*@
2447     MatMultAdd -  Computes v3 = v2 + A * v1.
2448 
2449     Neighbor-wise Collective on Mat
2450 
2451     Input Parameters:
2452 +   mat - the matrix
2453 -   v1, v2 - the vectors
2454 
2455     Output Parameters:
2456 .   v3 - the result
2457 
2458     Notes:
2459     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2460     call MatMultAdd(A,v1,v2,v1).
2461 
2462     Level: beginner
2463 
2464 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2465 @*/
2466 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2467 {
2468   PetscErrorCode ierr;
2469 
2470   PetscFunctionBegin;
2471   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2472   PetscValidType(mat,1);
2473   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2474   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2475   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2476 
2477   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2478   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2479   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);
2480   /* 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);
2481      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); */
2482   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);
2483   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);
2484   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2485   MatCheckPreallocated(mat,1);
2486 
2487   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name);
2488   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2489   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2490   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2491   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2492   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2493   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2494   PetscFunctionReturn(0);
2495 }
2496 
2497 /*@
2498    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2499 
2500    Neighbor-wise Collective on Mat
2501 
2502    Input Parameters:
2503 +  mat - the matrix
2504 -  v1, v2 - the vectors
2505 
2506    Output Parameters:
2507 .  v3 - the result
2508 
2509    Notes:
2510    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2511    call MatMultTransposeAdd(A,v1,v2,v1).
2512 
2513    Level: beginner
2514 
2515 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2516 @*/
2517 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2518 {
2519   PetscErrorCode ierr;
2520 
2521   PetscFunctionBegin;
2522   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2523   PetscValidType(mat,1);
2524   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2525   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2526   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2527 
2528   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2529   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2530   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2531   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2532   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);
2533   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);
2534   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);
2535   MatCheckPreallocated(mat,1);
2536 
2537   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2538   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2539   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2540   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2541   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2542   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2543   PetscFunctionReturn(0);
2544 }
2545 
2546 /*@
2547    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2548 
2549    Neighbor-wise Collective on Mat
2550 
2551    Input Parameters:
2552 +  mat - the matrix
2553 -  v1, v2 - the vectors
2554 
2555    Output Parameters:
2556 .  v3 - the result
2557 
2558    Notes:
2559    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2560    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2561 
2562    Level: beginner
2563 
2564 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2565 @*/
2566 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2567 {
2568   PetscErrorCode ierr;
2569 
2570   PetscFunctionBegin;
2571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2572   PetscValidType(mat,1);
2573   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2574   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2575   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2576 
2577   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2578   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2579   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2580   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);
2581   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);
2582   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);
2583   MatCheckPreallocated(mat,1);
2584 
2585   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2586   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2587   if (mat->ops->multhermitiantransposeadd) {
2588     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2589   } else {
2590     Vec w,z;
2591     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2592     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2593     ierr = VecConjugate(w);CHKERRQ(ierr);
2594     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2595     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2596     ierr = VecDestroy(&w);CHKERRQ(ierr);
2597     ierr = VecConjugate(z);CHKERRQ(ierr);
2598     if (v2 != v3) {
2599       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2600     } else {
2601       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2602     }
2603     ierr = VecDestroy(&z);CHKERRQ(ierr);
2604   }
2605   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2606   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2607   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2608   PetscFunctionReturn(0);
2609 }
2610 
2611 /*@
2612    MatMultConstrained - The inner multiplication routine for a
2613    constrained matrix P^T A P.
2614 
2615    Neighbor-wise Collective on Mat
2616 
2617    Input Parameters:
2618 +  mat - the matrix
2619 -  x   - the vector to be multilplied
2620 
2621    Output Parameters:
2622 .  y - the result
2623 
2624    Notes:
2625    The vectors x and y cannot be the same.  I.e., one cannot
2626    call MatMult(A,y,y).
2627 
2628    Level: beginner
2629 
2630 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2631 @*/
2632 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2633 {
2634   PetscErrorCode ierr;
2635 
2636   PetscFunctionBegin;
2637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2638   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2639   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2640   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2641   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2642   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2643   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);
2644   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);
2645   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);
2646 
2647   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2648   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2649   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2650   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2651   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2652   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2653   PetscFunctionReturn(0);
2654 }
2655 
2656 /*@
2657    MatMultTransposeConstrained - The inner multiplication routine for a
2658    constrained matrix P^T A^T P.
2659 
2660    Neighbor-wise Collective on Mat
2661 
2662    Input Parameters:
2663 +  mat - the matrix
2664 -  x   - the vector to be multilplied
2665 
2666    Output Parameters:
2667 .  y - the result
2668 
2669    Notes:
2670    The vectors x and y cannot be the same.  I.e., one cannot
2671    call MatMult(A,y,y).
2672 
2673    Level: beginner
2674 
2675 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2676 @*/
2677 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2678 {
2679   PetscErrorCode ierr;
2680 
2681   PetscFunctionBegin;
2682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2683   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2684   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2685   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2686   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2687   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2688   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);
2689   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);
2690 
2691   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2692   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2693   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2694   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2695   PetscFunctionReturn(0);
2696 }
2697 
2698 /*@C
2699    MatGetFactorType - gets the type of factorization it is
2700 
2701    Not Collective
2702 
2703    Input Parameters:
2704 .  mat - the matrix
2705 
2706    Output Parameters:
2707 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2708 
2709    Level: intermediate
2710 
2711 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2712 @*/
2713 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2714 {
2715   PetscFunctionBegin;
2716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2717   PetscValidType(mat,1);
2718   PetscValidPointer(t,2);
2719   *t = mat->factortype;
2720   PetscFunctionReturn(0);
2721 }
2722 
2723 /*@C
2724    MatSetFactorType - sets the type of factorization it is
2725 
2726    Logically Collective on Mat
2727 
2728    Input Parameters:
2729 +  mat - the matrix
2730 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2731 
2732    Level: intermediate
2733 
2734 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2735 @*/
2736 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2737 {
2738   PetscFunctionBegin;
2739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2740   PetscValidType(mat,1);
2741   mat->factortype = t;
2742   PetscFunctionReturn(0);
2743 }
2744 
2745 /* ------------------------------------------------------------*/
2746 /*@C
2747    MatGetInfo - Returns information about matrix storage (number of
2748    nonzeros, memory, etc.).
2749 
2750    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2751 
2752    Input Parameters:
2753 .  mat - the matrix
2754 
2755    Output Parameters:
2756 +  flag - flag indicating the type of parameters to be returned
2757    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2758    MAT_GLOBAL_SUM - sum over all processors)
2759 -  info - matrix information context
2760 
2761    Notes:
2762    The MatInfo context contains a variety of matrix data, including
2763    number of nonzeros allocated and used, number of mallocs during
2764    matrix assembly, etc.  Additional information for factored matrices
2765    is provided (such as the fill ratio, number of mallocs during
2766    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2767    when using the runtime options
2768 $       -info -mat_view ::ascii_info
2769 
2770    Example for C/C++ Users:
2771    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2772    data within the MatInfo context.  For example,
2773 .vb
2774       MatInfo info;
2775       Mat     A;
2776       double  mal, nz_a, nz_u;
2777 
2778       MatGetInfo(A,MAT_LOCAL,&info);
2779       mal  = info.mallocs;
2780       nz_a = info.nz_allocated;
2781 .ve
2782 
2783    Example for Fortran Users:
2784    Fortran users should declare info as a double precision
2785    array of dimension MAT_INFO_SIZE, and then extract the parameters
2786    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2787    a complete list of parameter names.
2788 .vb
2789       double  precision info(MAT_INFO_SIZE)
2790       double  precision mal, nz_a
2791       Mat     A
2792       integer ierr
2793 
2794       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2795       mal = info(MAT_INFO_MALLOCS)
2796       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2797 .ve
2798 
2799     Level: intermediate
2800 
2801     Developer Note: fortran interface is not autogenerated as the f90
2802     interface defintion cannot be generated correctly [due to MatInfo]
2803 
2804 .seealso: MatStashGetInfo()
2805 
2806 @*/
2807 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2808 {
2809   PetscErrorCode ierr;
2810 
2811   PetscFunctionBegin;
2812   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2813   PetscValidType(mat,1);
2814   PetscValidPointer(info,3);
2815   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2816   MatCheckPreallocated(mat,1);
2817   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2818   PetscFunctionReturn(0);
2819 }
2820 
2821 /*
2822    This is used by external packages where it is not easy to get the info from the actual
2823    matrix factorization.
2824 */
2825 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2826 {
2827   PetscErrorCode ierr;
2828 
2829   PetscFunctionBegin;
2830   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2831   PetscFunctionReturn(0);
2832 }
2833 
2834 /* ----------------------------------------------------------*/
2835 
2836 /*@C
2837    MatLUFactor - Performs in-place LU factorization of matrix.
2838 
2839    Collective on Mat
2840 
2841    Input Parameters:
2842 +  mat - the matrix
2843 .  row - row permutation
2844 .  col - column permutation
2845 -  info - options for factorization, includes
2846 $          fill - expected fill as ratio of original fill.
2847 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2848 $                   Run with the option -info to determine an optimal value to use
2849 
2850    Notes:
2851    Most users should employ the simplified KSP interface for linear solvers
2852    instead of working directly with matrix algebra routines such as this.
2853    See, e.g., KSPCreate().
2854 
2855    This changes the state of the matrix to a factored matrix; it cannot be used
2856    for example with MatSetValues() unless one first calls MatSetUnfactored().
2857 
2858    Level: developer
2859 
2860 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2861           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2862 
2863     Developer Note: fortran interface is not autogenerated as the f90
2864     interface defintion cannot be generated correctly [due to MatFactorInfo]
2865 
2866 @*/
2867 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2868 {
2869   PetscErrorCode ierr;
2870   MatFactorInfo  tinfo;
2871 
2872   PetscFunctionBegin;
2873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2874   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2875   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2876   if (info) PetscValidPointer(info,4);
2877   PetscValidType(mat,1);
2878   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2879   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2880   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2881   MatCheckPreallocated(mat,1);
2882   if (!info) {
2883     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2884     info = &tinfo;
2885   }
2886 
2887   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2888   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2889   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2890   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2891   PetscFunctionReturn(0);
2892 }
2893 
2894 /*@C
2895    MatILUFactor - Performs in-place ILU factorization of matrix.
2896 
2897    Collective on Mat
2898 
2899    Input Parameters:
2900 +  mat - the matrix
2901 .  row - row permutation
2902 .  col - column permutation
2903 -  info - structure containing
2904 $      levels - number of levels of fill.
2905 $      expected fill - as ratio of original fill.
2906 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2907                 missing diagonal entries)
2908 
2909    Notes:
2910    Probably really in-place only when level of fill is zero, otherwise allocates
2911    new space to store factored matrix and deletes previous memory.
2912 
2913    Most users should employ the simplified KSP interface for linear solvers
2914    instead of working directly with matrix algebra routines such as this.
2915    See, e.g., KSPCreate().
2916 
2917    Level: developer
2918 
2919 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2920 
2921     Developer Note: fortran interface is not autogenerated as the f90
2922     interface defintion cannot be generated correctly [due to MatFactorInfo]
2923 
2924 @*/
2925 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2926 {
2927   PetscErrorCode ierr;
2928 
2929   PetscFunctionBegin;
2930   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2931   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2932   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2933   PetscValidPointer(info,4);
2934   PetscValidType(mat,1);
2935   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2936   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2937   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2938   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2939   MatCheckPreallocated(mat,1);
2940 
2941   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2942   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2943   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2944   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2945   PetscFunctionReturn(0);
2946 }
2947 
2948 /*@C
2949    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2950    Call this routine before calling MatLUFactorNumeric().
2951 
2952    Collective on Mat
2953 
2954    Input Parameters:
2955 +  fact - the factor matrix obtained with MatGetFactor()
2956 .  mat - the matrix
2957 .  row, col - row and column permutations
2958 -  info - options for factorization, includes
2959 $          fill - expected fill as ratio of original fill.
2960 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2961 $                   Run with the option -info to determine an optimal value to use
2962 
2963 
2964    Notes:
2965     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2966 
2967    Most users should employ the simplified KSP interface for linear solvers
2968    instead of working directly with matrix algebra routines such as this.
2969    See, e.g., KSPCreate().
2970 
2971    Level: developer
2972 
2973 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2974 
2975     Developer Note: fortran interface is not autogenerated as the f90
2976     interface defintion cannot be generated correctly [due to MatFactorInfo]
2977 
2978 @*/
2979 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2980 {
2981   PetscErrorCode ierr;
2982   MatFactorInfo  tinfo;
2983 
2984   PetscFunctionBegin;
2985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2986   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2987   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2988   if (info) PetscValidPointer(info,4);
2989   PetscValidType(mat,1);
2990   PetscValidPointer(fact,5);
2991   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2992   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2993   if (!(fact)->ops->lufactorsymbolic) {
2994     MatSolverType spackage;
2995     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
2996     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2997   }
2998   MatCheckPreallocated(mat,2);
2999   if (!info) {
3000     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3001     info = &tinfo;
3002   }
3003 
3004   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3005   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3006   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3007   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3008   PetscFunctionReturn(0);
3009 }
3010 
3011 /*@C
3012    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3013    Call this routine after first calling MatLUFactorSymbolic().
3014 
3015    Collective on Mat
3016 
3017    Input Parameters:
3018 +  fact - the factor matrix obtained with MatGetFactor()
3019 .  mat - the matrix
3020 -  info - options for factorization
3021 
3022    Notes:
3023    See MatLUFactor() for in-place factorization.  See
3024    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3025 
3026    Most users should employ the simplified KSP interface for linear solvers
3027    instead of working directly with matrix algebra routines such as this.
3028    See, e.g., KSPCreate().
3029 
3030    Level: developer
3031 
3032 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3033 
3034     Developer Note: fortran interface is not autogenerated as the f90
3035     interface defintion cannot be generated correctly [due to MatFactorInfo]
3036 
3037 @*/
3038 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3039 {
3040   MatFactorInfo  tinfo;
3041   PetscErrorCode ierr;
3042 
3043   PetscFunctionBegin;
3044   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3045   PetscValidType(mat,1);
3046   PetscValidPointer(fact,2);
3047   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3048   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3049   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);
3050 
3051   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3052   MatCheckPreallocated(mat,2);
3053   if (!info) {
3054     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3055     info = &tinfo;
3056   }
3057 
3058   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3059   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3060   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3061   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3062   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3063   PetscFunctionReturn(0);
3064 }
3065 
3066 /*@C
3067    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3068    symmetric matrix.
3069 
3070    Collective on Mat
3071 
3072    Input Parameters:
3073 +  mat - the matrix
3074 .  perm - row and column permutations
3075 -  f - expected fill as ratio of original fill
3076 
3077    Notes:
3078    See MatLUFactor() for the nonsymmetric case.  See also
3079    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3080 
3081    Most users should employ the simplified KSP interface for linear solvers
3082    instead of working directly with matrix algebra routines such as this.
3083    See, e.g., KSPCreate().
3084 
3085    Level: developer
3086 
3087 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3088           MatGetOrdering()
3089 
3090     Developer Note: fortran interface is not autogenerated as the f90
3091     interface defintion cannot be generated correctly [due to MatFactorInfo]
3092 
3093 @*/
3094 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3095 {
3096   PetscErrorCode ierr;
3097   MatFactorInfo  tinfo;
3098 
3099   PetscFunctionBegin;
3100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3101   PetscValidType(mat,1);
3102   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3103   if (info) PetscValidPointer(info,3);
3104   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3105   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3106   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3107   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);
3108   MatCheckPreallocated(mat,1);
3109   if (!info) {
3110     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3111     info = &tinfo;
3112   }
3113 
3114   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3115   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3116   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3117   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3118   PetscFunctionReturn(0);
3119 }
3120 
3121 /*@C
3122    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3123    of a symmetric matrix.
3124 
3125    Collective on Mat
3126 
3127    Input Parameters:
3128 +  fact - the factor matrix obtained with MatGetFactor()
3129 .  mat - the matrix
3130 .  perm - row and column permutations
3131 -  info - options for factorization, includes
3132 $          fill - expected fill as ratio of original fill.
3133 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3134 $                   Run with the option -info to determine an optimal value to use
3135 
3136    Notes:
3137    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3138    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3139 
3140    Most users should employ the simplified KSP interface for linear solvers
3141    instead of working directly with matrix algebra routines such as this.
3142    See, e.g., KSPCreate().
3143 
3144    Level: developer
3145 
3146 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3147           MatGetOrdering()
3148 
3149     Developer Note: fortran interface is not autogenerated as the f90
3150     interface defintion cannot be generated correctly [due to MatFactorInfo]
3151 
3152 @*/
3153 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3154 {
3155   PetscErrorCode ierr;
3156   MatFactorInfo  tinfo;
3157 
3158   PetscFunctionBegin;
3159   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3160   PetscValidType(mat,1);
3161   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3162   if (info) PetscValidPointer(info,3);
3163   PetscValidPointer(fact,4);
3164   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3165   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3166   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3167   if (!(fact)->ops->choleskyfactorsymbolic) {
3168     MatSolverType spackage;
3169     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3170     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3171   }
3172   MatCheckPreallocated(mat,2);
3173   if (!info) {
3174     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3175     info = &tinfo;
3176   }
3177 
3178   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3179   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3180   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3181   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3182   PetscFunctionReturn(0);
3183 }
3184 
3185 /*@C
3186    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3187    of a symmetric matrix. Call this routine after first calling
3188    MatCholeskyFactorSymbolic().
3189 
3190    Collective on Mat
3191 
3192    Input Parameters:
3193 +  fact - the factor matrix obtained with MatGetFactor()
3194 .  mat - the initial matrix
3195 .  info - options for factorization
3196 -  fact - the symbolic factor of mat
3197 
3198 
3199    Notes:
3200    Most users should employ the simplified KSP interface for linear solvers
3201    instead of working directly with matrix algebra routines such as this.
3202    See, e.g., KSPCreate().
3203 
3204    Level: developer
3205 
3206 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3207 
3208     Developer Note: fortran interface is not autogenerated as the f90
3209     interface defintion cannot be generated correctly [due to MatFactorInfo]
3210 
3211 @*/
3212 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3213 {
3214   MatFactorInfo  tinfo;
3215   PetscErrorCode ierr;
3216 
3217   PetscFunctionBegin;
3218   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3219   PetscValidType(mat,1);
3220   PetscValidPointer(fact,2);
3221   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3222   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3223   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3224   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);
3225   MatCheckPreallocated(mat,2);
3226   if (!info) {
3227     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3228     info = &tinfo;
3229   }
3230 
3231   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3232   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3233   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3234   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3235   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3236   PetscFunctionReturn(0);
3237 }
3238 
3239 /* ----------------------------------------------------------------*/
3240 /*@
3241    MatSolve - Solves A x = b, given a factored matrix.
3242 
3243    Neighbor-wise Collective on Mat
3244 
3245    Input Parameters:
3246 +  mat - the factored matrix
3247 -  b - the right-hand-side vector
3248 
3249    Output Parameter:
3250 .  x - the result vector
3251 
3252    Notes:
3253    The vectors b and x cannot be the same.  I.e., one cannot
3254    call MatSolve(A,x,x).
3255 
3256    Notes:
3257    Most users should employ the simplified KSP interface for linear solvers
3258    instead of working directly with matrix algebra routines such as this.
3259    See, e.g., KSPCreate().
3260 
3261    Level: developer
3262 
3263 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3264 @*/
3265 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3266 {
3267   PetscErrorCode ierr;
3268 
3269   PetscFunctionBegin;
3270   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3271   PetscValidType(mat,1);
3272   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3273   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3274   PetscCheckSameComm(mat,1,b,2);
3275   PetscCheckSameComm(mat,1,x,3);
3276   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3277   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);
3278   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);
3279   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);
3280   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3281   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3282   MatCheckPreallocated(mat,1);
3283 
3284   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3285   if (mat->factorerrortype) {
3286     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3287     ierr = VecSetInf(x);CHKERRQ(ierr);
3288   } else {
3289     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3290     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3291   }
3292   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3293   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3294   PetscFunctionReturn(0);
3295 }
3296 
3297 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3298 {
3299   PetscErrorCode ierr;
3300   Vec            b,x;
3301   PetscInt       m,N,i;
3302   PetscScalar    *bb,*xx;
3303 
3304   PetscFunctionBegin;
3305   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3306   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3307   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3308   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3309   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3310   for (i=0; i<N; i++) {
3311     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3312     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3313     if (trans) {
3314       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3315     } else {
3316       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3317     }
3318     ierr = VecResetArray(x);CHKERRQ(ierr);
3319     ierr = VecResetArray(b);CHKERRQ(ierr);
3320   }
3321   ierr = VecDestroy(&b);CHKERRQ(ierr);
3322   ierr = VecDestroy(&x);CHKERRQ(ierr);
3323   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3324   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3325   PetscFunctionReturn(0);
3326 }
3327 
3328 /*@
3329    MatMatSolve - Solves A X = B, given a factored matrix.
3330 
3331    Neighbor-wise Collective on Mat
3332 
3333    Input Parameters:
3334 +  A - the factored matrix
3335 -  B - the right-hand-side matrix  (dense matrix)
3336 
3337    Output Parameter:
3338 .  X - the result matrix (dense matrix)
3339 
3340    Notes:
3341    The matrices b and x cannot be the same.  I.e., one cannot
3342    call MatMatSolve(A,x,x).
3343 
3344    Notes:
3345    Most users should usually employ the simplified KSP interface for linear solvers
3346    instead of working directly with matrix algebra routines such as this.
3347    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3348    at a time.
3349 
3350    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3351    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3352 
3353    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3354 
3355    Level: developer
3356 
3357 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3358 @*/
3359 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3360 {
3361   PetscErrorCode ierr;
3362 
3363   PetscFunctionBegin;
3364   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3365   PetscValidType(A,1);
3366   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3367   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3368   PetscCheckSameComm(A,1,B,2);
3369   PetscCheckSameComm(A,1,X,3);
3370   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3371   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);
3372   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);
3373   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");
3374   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3375   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3376   MatCheckPreallocated(A,1);
3377 
3378   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3379   if (!A->ops->matsolve) {
3380     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3381     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3382   } else {
3383     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3384   }
3385   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3386   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3387   PetscFunctionReturn(0);
3388 }
3389 
3390 /*@
3391    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3392 
3393    Neighbor-wise Collective on Mat
3394 
3395    Input Parameters:
3396 +  A - the factored matrix
3397 -  B - the right-hand-side matrix  (dense matrix)
3398 
3399    Output Parameter:
3400 .  X - the result matrix (dense matrix)
3401 
3402    Notes:
3403    The matrices B and X cannot be the same.  I.e., one cannot
3404    call MatMatSolveTranspose(A,X,X).
3405 
3406    Notes:
3407    Most users should usually employ the simplified KSP interface for linear solvers
3408    instead of working directly with matrix algebra routines such as this.
3409    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3410    at a time.
3411 
3412    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3413 
3414    Level: developer
3415 
3416 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3417 @*/
3418 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3419 {
3420   PetscErrorCode ierr;
3421 
3422   PetscFunctionBegin;
3423   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3424   PetscValidType(A,1);
3425   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3426   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3427   PetscCheckSameComm(A,1,B,2);
3428   PetscCheckSameComm(A,1,X,3);
3429   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3430   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);
3431   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);
3432   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);
3433   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");
3434   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3435   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3436   MatCheckPreallocated(A,1);
3437 
3438   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3439   if (!A->ops->matsolvetranspose) {
3440     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3441     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3442   } else {
3443     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3444   }
3445   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3446   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3447   PetscFunctionReturn(0);
3448 }
3449 
3450 /*@
3451    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3452 
3453    Neighbor-wise Collective on Mat
3454 
3455    Input Parameters:
3456 +  A - the factored matrix
3457 -  Bt - the transpose of right-hand-side matrix
3458 
3459    Output Parameter:
3460 .  X - the result matrix (dense matrix)
3461 
3462    Notes:
3463    Most users should usually employ the simplified KSP interface for linear solvers
3464    instead of working directly with matrix algebra routines such as this.
3465    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3466    at a time.
3467 
3468    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().
3469 
3470    Level: developer
3471 
3472 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3473 @*/
3474 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3475 {
3476   PetscErrorCode ierr;
3477 
3478   PetscFunctionBegin;
3479   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3480   PetscValidType(A,1);
3481   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3482   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3483   PetscCheckSameComm(A,1,Bt,2);
3484   PetscCheckSameComm(A,1,X,3);
3485 
3486   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3487   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);
3488   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);
3489   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");
3490   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3491   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3492   MatCheckPreallocated(A,1);
3493 
3494   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3495   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3496   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3497   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3498   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3499   PetscFunctionReturn(0);
3500 }
3501 
3502 /*@
3503    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3504                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3505 
3506    Neighbor-wise Collective on Mat
3507 
3508    Input Parameters:
3509 +  mat - the factored matrix
3510 -  b - the right-hand-side vector
3511 
3512    Output Parameter:
3513 .  x - the result vector
3514 
3515    Notes:
3516    MatSolve() should be used for most applications, as it performs
3517    a forward solve followed by a backward solve.
3518 
3519    The vectors b and x cannot be the same,  i.e., one cannot
3520    call MatForwardSolve(A,x,x).
3521 
3522    For matrix in seqsbaij format with block size larger than 1,
3523    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3524    MatForwardSolve() solves U^T*D y = b, and
3525    MatBackwardSolve() solves U x = y.
3526    Thus they do not provide a symmetric preconditioner.
3527 
3528    Most users should employ the simplified KSP interface for linear solvers
3529    instead of working directly with matrix algebra routines such as this.
3530    See, e.g., KSPCreate().
3531 
3532    Level: developer
3533 
3534 .seealso: MatSolve(), MatBackwardSolve()
3535 @*/
3536 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3537 {
3538   PetscErrorCode ierr;
3539 
3540   PetscFunctionBegin;
3541   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3542   PetscValidType(mat,1);
3543   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3544   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3545   PetscCheckSameComm(mat,1,b,2);
3546   PetscCheckSameComm(mat,1,x,3);
3547   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3548   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);
3549   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);
3550   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);
3551   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3552   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3553   MatCheckPreallocated(mat,1);
3554 
3555   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3556   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3557   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3558   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3559   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3560   PetscFunctionReturn(0);
3561 }
3562 
3563 /*@
3564    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3565                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3566 
3567    Neighbor-wise Collective on Mat
3568 
3569    Input Parameters:
3570 +  mat - the factored matrix
3571 -  b - the right-hand-side vector
3572 
3573    Output Parameter:
3574 .  x - the result vector
3575 
3576    Notes:
3577    MatSolve() should be used for most applications, as it performs
3578    a forward solve followed by a backward solve.
3579 
3580    The vectors b and x cannot be the same.  I.e., one cannot
3581    call MatBackwardSolve(A,x,x).
3582 
3583    For matrix in seqsbaij format with block size larger than 1,
3584    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3585    MatForwardSolve() solves U^T*D y = b, and
3586    MatBackwardSolve() solves U x = y.
3587    Thus they do not provide a symmetric preconditioner.
3588 
3589    Most users should employ the simplified KSP interface for linear solvers
3590    instead of working directly with matrix algebra routines such as this.
3591    See, e.g., KSPCreate().
3592 
3593    Level: developer
3594 
3595 .seealso: MatSolve(), MatForwardSolve()
3596 @*/
3597 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3598 {
3599   PetscErrorCode ierr;
3600 
3601   PetscFunctionBegin;
3602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3603   PetscValidType(mat,1);
3604   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3605   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3606   PetscCheckSameComm(mat,1,b,2);
3607   PetscCheckSameComm(mat,1,x,3);
3608   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3609   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);
3610   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);
3611   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);
3612   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3613   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3614   MatCheckPreallocated(mat,1);
3615 
3616   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3617   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3618   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3619   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3620   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3621   PetscFunctionReturn(0);
3622 }
3623 
3624 /*@
3625    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3626 
3627    Neighbor-wise Collective on Mat
3628 
3629    Input Parameters:
3630 +  mat - the factored matrix
3631 .  b - the right-hand-side vector
3632 -  y - the vector to be added to
3633 
3634    Output Parameter:
3635 .  x - the result vector
3636 
3637    Notes:
3638    The vectors b and x cannot be the same.  I.e., one cannot
3639    call MatSolveAdd(A,x,y,x).
3640 
3641    Most users should employ the simplified KSP interface for linear solvers
3642    instead of working directly with matrix algebra routines such as this.
3643    See, e.g., KSPCreate().
3644 
3645    Level: developer
3646 
3647 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3648 @*/
3649 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3650 {
3651   PetscScalar    one = 1.0;
3652   Vec            tmp;
3653   PetscErrorCode ierr;
3654 
3655   PetscFunctionBegin;
3656   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3657   PetscValidType(mat,1);
3658   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3659   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3660   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3661   PetscCheckSameComm(mat,1,b,2);
3662   PetscCheckSameComm(mat,1,y,2);
3663   PetscCheckSameComm(mat,1,x,3);
3664   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3665   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);
3666   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);
3667   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);
3668   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);
3669   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);
3670   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3671   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3672   MatCheckPreallocated(mat,1);
3673 
3674   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3675   if (mat->ops->solveadd) {
3676     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3677   } else {
3678     /* do the solve then the add manually */
3679     if (x != y) {
3680       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3681       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3682     } else {
3683       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3684       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3685       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3686       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3687       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3688       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3689     }
3690   }
3691   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3692   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3693   PetscFunctionReturn(0);
3694 }
3695 
3696 /*@
3697    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3698 
3699    Neighbor-wise Collective on Mat
3700 
3701    Input Parameters:
3702 +  mat - the factored matrix
3703 -  b - the right-hand-side vector
3704 
3705    Output Parameter:
3706 .  x - the result vector
3707 
3708    Notes:
3709    The vectors b and x cannot be the same.  I.e., one cannot
3710    call MatSolveTranspose(A,x,x).
3711 
3712    Most users should employ the simplified KSP interface for linear solvers
3713    instead of working directly with matrix algebra routines such as this.
3714    See, e.g., KSPCreate().
3715 
3716    Level: developer
3717 
3718 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3719 @*/
3720 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3721 {
3722   PetscErrorCode ierr;
3723 
3724   PetscFunctionBegin;
3725   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3726   PetscValidType(mat,1);
3727   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3728   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3729   PetscCheckSameComm(mat,1,b,2);
3730   PetscCheckSameComm(mat,1,x,3);
3731   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3732   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);
3733   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);
3734   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3735   MatCheckPreallocated(mat,1);
3736   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3737   if (mat->factorerrortype) {
3738     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3739     ierr = VecSetInf(x);CHKERRQ(ierr);
3740   } else {
3741     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3742     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3743   }
3744   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3745   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3746   PetscFunctionReturn(0);
3747 }
3748 
3749 /*@
3750    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3751                       factored matrix.
3752 
3753    Neighbor-wise Collective on Mat
3754 
3755    Input Parameters:
3756 +  mat - the factored matrix
3757 .  b - the right-hand-side vector
3758 -  y - the vector to be added to
3759 
3760    Output Parameter:
3761 .  x - the result vector
3762 
3763    Notes:
3764    The vectors b and x cannot be the same.  I.e., one cannot
3765    call MatSolveTransposeAdd(A,x,y,x).
3766 
3767    Most users should employ the simplified KSP interface for linear solvers
3768    instead of working directly with matrix algebra routines such as this.
3769    See, e.g., KSPCreate().
3770 
3771    Level: developer
3772 
3773 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3774 @*/
3775 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3776 {
3777   PetscScalar    one = 1.0;
3778   PetscErrorCode ierr;
3779   Vec            tmp;
3780 
3781   PetscFunctionBegin;
3782   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3783   PetscValidType(mat,1);
3784   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3785   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3786   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3787   PetscCheckSameComm(mat,1,b,2);
3788   PetscCheckSameComm(mat,1,y,3);
3789   PetscCheckSameComm(mat,1,x,4);
3790   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3791   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);
3792   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);
3793   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);
3794   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);
3795   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3796   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3797   MatCheckPreallocated(mat,1);
3798 
3799   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3800   if (mat->ops->solvetransposeadd) {
3801     if (mat->factorerrortype) {
3802       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3803       ierr = VecSetInf(x);CHKERRQ(ierr);
3804     } else {
3805       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3806     }
3807   } else {
3808     /* do the solve then the add manually */
3809     if (x != y) {
3810       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3811       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3812     } else {
3813       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3814       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3815       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3816       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3817       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3818       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3819     }
3820   }
3821   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3822   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3823   PetscFunctionReturn(0);
3824 }
3825 /* ----------------------------------------------------------------*/
3826 
3827 /*@
3828    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3829 
3830    Neighbor-wise Collective on Mat
3831 
3832    Input Parameters:
3833 +  mat - the matrix
3834 .  b - the right hand side
3835 .  omega - the relaxation factor
3836 .  flag - flag indicating the type of SOR (see below)
3837 .  shift -  diagonal shift
3838 .  its - the number of iterations
3839 -  lits - the number of local iterations
3840 
3841    Output Parameters:
3842 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3843 
3844    SOR Flags:
3845 +     SOR_FORWARD_SWEEP - forward SOR
3846 .     SOR_BACKWARD_SWEEP - backward SOR
3847 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3848 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3849 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3850 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3851 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3852          upper/lower triangular part of matrix to
3853          vector (with omega)
3854 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
3855 
3856    Notes:
3857    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3858    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3859    on each processor.
3860 
3861    Application programmers will not generally use MatSOR() directly,
3862    but instead will employ the KSP/PC interface.
3863 
3864    Notes:
3865     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3866 
3867    Notes for Advanced Users:
3868    The flags are implemented as bitwise inclusive or operations.
3869    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3870    to specify a zero initial guess for SSOR.
3871 
3872    Most users should employ the simplified KSP interface for linear solvers
3873    instead of working directly with matrix algebra routines such as this.
3874    See, e.g., KSPCreate().
3875 
3876    Vectors x and b CANNOT be the same
3877 
3878    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3879 
3880    Level: developer
3881 
3882 @*/
3883 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3884 {
3885   PetscErrorCode ierr;
3886 
3887   PetscFunctionBegin;
3888   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3889   PetscValidType(mat,1);
3890   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3891   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3892   PetscCheckSameComm(mat,1,b,2);
3893   PetscCheckSameComm(mat,1,x,8);
3894   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3895   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3896   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3897   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);
3898   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);
3899   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);
3900   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3901   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3902   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3903 
3904   MatCheckPreallocated(mat,1);
3905   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3906   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3907   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3908   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3909   PetscFunctionReturn(0);
3910 }
3911 
3912 /*
3913       Default matrix copy routine.
3914 */
3915 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3916 {
3917   PetscErrorCode    ierr;
3918   PetscInt          i,rstart = 0,rend = 0,nz;
3919   const PetscInt    *cwork;
3920   const PetscScalar *vwork;
3921 
3922   PetscFunctionBegin;
3923   if (B->assembled) {
3924     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3925   }
3926   if (str == SAME_NONZERO_PATTERN) {
3927     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3928     for (i=rstart; i<rend; i++) {
3929       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3930       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3931       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3932     }
3933   } else {
3934     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
3935   }
3936   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3937   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3938   PetscFunctionReturn(0);
3939 }
3940 
3941 /*@
3942    MatCopy - Copies a matrix to another matrix.
3943 
3944    Collective on Mat
3945 
3946    Input Parameters:
3947 +  A - the matrix
3948 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3949 
3950    Output Parameter:
3951 .  B - where the copy is put
3952 
3953    Notes:
3954    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3955    same nonzero pattern or the routine will crash.
3956 
3957    MatCopy() copies the matrix entries of a matrix to another existing
3958    matrix (after first zeroing the second matrix).  A related routine is
3959    MatConvert(), which first creates a new matrix and then copies the data.
3960 
3961    Level: intermediate
3962 
3963 .seealso: MatConvert(), MatDuplicate()
3964 
3965 @*/
3966 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3967 {
3968   PetscErrorCode ierr;
3969   PetscInt       i;
3970 
3971   PetscFunctionBegin;
3972   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3973   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3974   PetscValidType(A,1);
3975   PetscValidType(B,2);
3976   PetscCheckSameComm(A,1,B,2);
3977   MatCheckPreallocated(B,2);
3978   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3979   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3980   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);
3981   MatCheckPreallocated(A,1);
3982   if (A == B) PetscFunctionReturn(0);
3983 
3984   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3985   if (A->ops->copy) {
3986     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3987   } else { /* generic conversion */
3988     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3989   }
3990 
3991   B->stencil.dim = A->stencil.dim;
3992   B->stencil.noc = A->stencil.noc;
3993   for (i=0; i<=A->stencil.dim; i++) {
3994     B->stencil.dims[i]   = A->stencil.dims[i];
3995     B->stencil.starts[i] = A->stencil.starts[i];
3996   }
3997 
3998   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3999   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4000   PetscFunctionReturn(0);
4001 }
4002 
4003 /*@C
4004    MatConvert - Converts a matrix to another matrix, either of the same
4005    or different type.
4006 
4007    Collective on Mat
4008 
4009    Input Parameters:
4010 +  mat - the matrix
4011 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4012    same type as the original matrix.
4013 -  reuse - denotes if the destination matrix is to be created or reused.
4014    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
4015    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).
4016 
4017    Output Parameter:
4018 .  M - pointer to place new matrix
4019 
4020    Notes:
4021    MatConvert() first creates a new matrix and then copies the data from
4022    the first matrix.  A related routine is MatCopy(), which copies the matrix
4023    entries of one matrix to another already existing matrix context.
4024 
4025    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4026    the MPI communicator of the generated matrix is always the same as the communicator
4027    of the input matrix.
4028 
4029    Level: intermediate
4030 
4031 .seealso: MatCopy(), MatDuplicate()
4032 @*/
4033 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4034 {
4035   PetscErrorCode ierr;
4036   PetscBool      sametype,issame,flg;
4037   char           convname[256],mtype[256];
4038   Mat            B;
4039 
4040   PetscFunctionBegin;
4041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4042   PetscValidType(mat,1);
4043   PetscValidPointer(M,3);
4044   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4045   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4046   MatCheckPreallocated(mat,1);
4047 
4048   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4049   if (flg) newtype = mtype;
4050 
4051   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4052   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4053   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4054   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");
4055 
4056   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4057     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4058     PetscFunctionReturn(0);
4059   }
4060 
4061   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4062     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4063     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4064   } else {
4065     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4066     const char     *prefix[3] = {"seq","mpi",""};
4067     PetscInt       i;
4068     /*
4069        Order of precedence:
4070        0) See if newtype is a superclass of the current matrix.
4071        1) See if a specialized converter is known to the current matrix.
4072        2) See if a specialized converter is known to the desired matrix class.
4073        3) See if a good general converter is registered for the desired class
4074           (as of 6/27/03 only MATMPIADJ falls into this category).
4075        4) See if a good general converter is known for the current matrix.
4076        5) Use a really basic converter.
4077     */
4078 
4079     /* 0) See if newtype is a superclass of the current matrix.
4080           i.e mat is mpiaij and newtype is aij */
4081     for (i=0; i<2; i++) {
4082       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4083       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4084       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4085       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4086       if (flg) {
4087         if (reuse == MAT_INPLACE_MATRIX) {
4088           PetscFunctionReturn(0);
4089         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4090           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4091           PetscFunctionReturn(0);
4092         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4093           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4094           PetscFunctionReturn(0);
4095         }
4096       }
4097     }
4098     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4099     for (i=0; i<3; i++) {
4100       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4101       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4102       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4103       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4104       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4105       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4106       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4107       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4108       if (conv) goto foundconv;
4109     }
4110 
4111     /* 2)  See if a specialized converter is known to the desired matrix class. */
4112     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4113     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4114     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4115     for (i=0; i<3; i++) {
4116       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4117       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4118       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4119       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4120       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4121       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4122       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4123       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4124       if (conv) {
4125         ierr = MatDestroy(&B);CHKERRQ(ierr);
4126         goto foundconv;
4127       }
4128     }
4129 
4130     /* 3) See if a good general converter is registered for the desired class */
4131     conv = B->ops->convertfrom;
4132     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4133     ierr = MatDestroy(&B);CHKERRQ(ierr);
4134     if (conv) goto foundconv;
4135 
4136     /* 4) See if a good general converter is known for the current matrix */
4137     if (mat->ops->convert) conv = mat->ops->convert;
4138 
4139     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4140     if (conv) goto foundconv;
4141 
4142     /* 5) Use a really basic converter. */
4143     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4144     conv = MatConvert_Basic;
4145 
4146 foundconv:
4147     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4148     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4149     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4150       /* the block sizes must be same if the mappings are copied over */
4151       (*M)->rmap->bs = mat->rmap->bs;
4152       (*M)->cmap->bs = mat->cmap->bs;
4153       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4154       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4155       (*M)->rmap->mapping = mat->rmap->mapping;
4156       (*M)->cmap->mapping = mat->cmap->mapping;
4157     }
4158     (*M)->stencil.dim = mat->stencil.dim;
4159     (*M)->stencil.noc = mat->stencil.noc;
4160     for (i=0; i<=mat->stencil.dim; i++) {
4161       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4162       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4163     }
4164     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4165   }
4166   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4167 
4168   /* Copy Mat options */
4169   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4170   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4171   PetscFunctionReturn(0);
4172 }
4173 
4174 /*@C
4175    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4176 
4177    Not Collective
4178 
4179    Input Parameter:
4180 .  mat - the matrix, must be a factored matrix
4181 
4182    Output Parameter:
4183 .   type - the string name of the package (do not free this string)
4184 
4185    Notes:
4186       In Fortran you pass in a empty string and the package name will be copied into it.
4187     (Make sure the string is long enough)
4188 
4189    Level: intermediate
4190 
4191 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4192 @*/
4193 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4194 {
4195   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4196 
4197   PetscFunctionBegin;
4198   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4199   PetscValidType(mat,1);
4200   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4201   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4202   if (!conv) {
4203     *type = MATSOLVERPETSC;
4204   } else {
4205     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4206   }
4207   PetscFunctionReturn(0);
4208 }
4209 
4210 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4211 struct _MatSolverTypeForSpecifcType {
4212   MatType                        mtype;
4213   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4214   MatSolverTypeForSpecifcType next;
4215 };
4216 
4217 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4218 struct _MatSolverTypeHolder {
4219   char                           *name;
4220   MatSolverTypeForSpecifcType handlers;
4221   MatSolverTypeHolder         next;
4222 };
4223 
4224 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4225 
4226 /*@C
4227    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4228 
4229    Input Parameters:
4230 +    package - name of the package, for example petsc or superlu
4231 .    mtype - the matrix type that works with this package
4232 .    ftype - the type of factorization supported by the package
4233 -    getfactor - routine that will create the factored matrix ready to be used
4234 
4235     Level: intermediate
4236 
4237 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4238 @*/
4239 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4240 {
4241   PetscErrorCode              ierr;
4242   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4243   PetscBool                   flg;
4244   MatSolverTypeForSpecifcType inext,iprev = NULL;
4245 
4246   PetscFunctionBegin;
4247   ierr = MatInitializePackage();CHKERRQ(ierr);
4248   if (!next) {
4249     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4250     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4251     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4252     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4253     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4254     PetscFunctionReturn(0);
4255   }
4256   while (next) {
4257     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4258     if (flg) {
4259       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4260       inext = next->handlers;
4261       while (inext) {
4262         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4263         if (flg) {
4264           inext->getfactor[(int)ftype-1] = getfactor;
4265           PetscFunctionReturn(0);
4266         }
4267         iprev = inext;
4268         inext = inext->next;
4269       }
4270       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4271       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4272       iprev->next->getfactor[(int)ftype-1] = getfactor;
4273       PetscFunctionReturn(0);
4274     }
4275     prev = next;
4276     next = next->next;
4277   }
4278   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4279   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4280   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4281   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4282   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4283   PetscFunctionReturn(0);
4284 }
4285 
4286 /*@C
4287    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4288 
4289    Input Parameters:
4290 +    package - name of the package, for example petsc or superlu
4291 .    ftype - the type of factorization supported by the package
4292 -    mtype - the matrix type that works with this package
4293 
4294    Output Parameters:
4295 +   foundpackage - PETSC_TRUE if the package was registered
4296 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4297 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4298 
4299     Level: intermediate
4300 
4301 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4302 @*/
4303 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4304 {
4305   PetscErrorCode                 ierr;
4306   MatSolverTypeHolder         next = MatSolverTypeHolders;
4307   PetscBool                      flg;
4308   MatSolverTypeForSpecifcType inext;
4309 
4310   PetscFunctionBegin;
4311   if (foundpackage) *foundpackage = PETSC_FALSE;
4312   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4313   if (getfactor)    *getfactor    = NULL;
4314 
4315   if (package) {
4316     while (next) {
4317       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4318       if (flg) {
4319         if (foundpackage) *foundpackage = PETSC_TRUE;
4320         inext = next->handlers;
4321         while (inext) {
4322           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4323           if (flg) {
4324             if (foundmtype) *foundmtype = PETSC_TRUE;
4325             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4326             PetscFunctionReturn(0);
4327           }
4328           inext = inext->next;
4329         }
4330       }
4331       next = next->next;
4332     }
4333   } else {
4334     while (next) {
4335       inext = next->handlers;
4336       while (inext) {
4337         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4338         if (flg && inext->getfactor[(int)ftype-1]) {
4339           if (foundpackage) *foundpackage = PETSC_TRUE;
4340           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4341           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4342           PetscFunctionReturn(0);
4343         }
4344         inext = inext->next;
4345       }
4346       next = next->next;
4347     }
4348   }
4349   PetscFunctionReturn(0);
4350 }
4351 
4352 PetscErrorCode MatSolverTypeDestroy(void)
4353 {
4354   PetscErrorCode              ierr;
4355   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4356   MatSolverTypeForSpecifcType inext,iprev;
4357 
4358   PetscFunctionBegin;
4359   while (next) {
4360     ierr = PetscFree(next->name);CHKERRQ(ierr);
4361     inext = next->handlers;
4362     while (inext) {
4363       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4364       iprev = inext;
4365       inext = inext->next;
4366       ierr = PetscFree(iprev);CHKERRQ(ierr);
4367     }
4368     prev = next;
4369     next = next->next;
4370     ierr = PetscFree(prev);CHKERRQ(ierr);
4371   }
4372   MatSolverTypeHolders = NULL;
4373   PetscFunctionReturn(0);
4374 }
4375 
4376 /*@C
4377    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4378 
4379    Collective on Mat
4380 
4381    Input Parameters:
4382 +  mat - the matrix
4383 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4384 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4385 
4386    Output Parameters:
4387 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4388 
4389    Notes:
4390       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4391      such as pastix, superlu, mumps etc.
4392 
4393       PETSc must have been ./configure to use the external solver, using the option --download-package
4394 
4395    Level: intermediate
4396 
4397 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4398 @*/
4399 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4400 {
4401   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4402   PetscBool      foundpackage,foundmtype;
4403 
4404   PetscFunctionBegin;
4405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4406   PetscValidType(mat,1);
4407 
4408   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4409   MatCheckPreallocated(mat,1);
4410 
4411   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4412   if (!foundpackage) {
4413     if (type) {
4414       SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type);
4415     } else {
4416       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4417     }
4418   }
4419   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4420   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);
4421 
4422 #if defined(PETSC_USE_COMPLEX)
4423   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4424 #endif
4425 
4426   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4427   PetscFunctionReturn(0);
4428 }
4429 
4430 /*@C
4431    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4432 
4433    Not Collective
4434 
4435    Input Parameters:
4436 +  mat - the matrix
4437 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4438 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4439 
4440    Output Parameter:
4441 .    flg - PETSC_TRUE if the factorization is available
4442 
4443    Notes:
4444       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4445      such as pastix, superlu, mumps etc.
4446 
4447       PETSc must have been ./configure to use the external solver, using the option --download-package
4448 
4449    Level: intermediate
4450 
4451 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4452 @*/
4453 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4454 {
4455   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4456 
4457   PetscFunctionBegin;
4458   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4459   PetscValidType(mat,1);
4460 
4461   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4462   MatCheckPreallocated(mat,1);
4463 
4464   *flg = PETSC_FALSE;
4465   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4466   if (gconv) {
4467     *flg = PETSC_TRUE;
4468   }
4469   PetscFunctionReturn(0);
4470 }
4471 
4472 #include <petscdmtypes.h>
4473 
4474 /*@
4475    MatDuplicate - Duplicates a matrix including the non-zero structure.
4476 
4477    Collective on Mat
4478 
4479    Input Parameters:
4480 +  mat - the matrix
4481 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4482         See the manual page for MatDuplicateOption for an explanation of these options.
4483 
4484    Output Parameter:
4485 .  M - pointer to place new matrix
4486 
4487    Level: intermediate
4488 
4489    Notes:
4490     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4491     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.
4492 
4493 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4494 @*/
4495 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4496 {
4497   PetscErrorCode ierr;
4498   Mat            B;
4499   PetscInt       i;
4500   DM             dm;
4501   void           (*viewf)(void);
4502 
4503   PetscFunctionBegin;
4504   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4505   PetscValidType(mat,1);
4506   PetscValidPointer(M,3);
4507   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4508   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4509   MatCheckPreallocated(mat,1);
4510 
4511   *M = 0;
4512   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4513   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4514   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4515   B    = *M;
4516 
4517   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4518   if (viewf) {
4519     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4520   }
4521 
4522   B->stencil.dim = mat->stencil.dim;
4523   B->stencil.noc = mat->stencil.noc;
4524   for (i=0; i<=mat->stencil.dim; i++) {
4525     B->stencil.dims[i]   = mat->stencil.dims[i];
4526     B->stencil.starts[i] = mat->stencil.starts[i];
4527   }
4528 
4529   B->nooffproczerorows = mat->nooffproczerorows;
4530   B->nooffprocentries  = mat->nooffprocentries;
4531 
4532   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4533   if (dm) {
4534     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4535   }
4536   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4537   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4538   PetscFunctionReturn(0);
4539 }
4540 
4541 /*@
4542    MatGetDiagonal - Gets the diagonal of a matrix.
4543 
4544    Logically Collective on Mat
4545 
4546    Input Parameters:
4547 +  mat - the matrix
4548 -  v - the vector for storing the diagonal
4549 
4550    Output Parameter:
4551 .  v - the diagonal of the matrix
4552 
4553    Level: intermediate
4554 
4555    Note:
4556    Currently only correct in parallel for square matrices.
4557 
4558 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4559 @*/
4560 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4561 {
4562   PetscErrorCode ierr;
4563 
4564   PetscFunctionBegin;
4565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4566   PetscValidType(mat,1);
4567   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4568   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4569   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4570   MatCheckPreallocated(mat,1);
4571 
4572   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4573   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4574   PetscFunctionReturn(0);
4575 }
4576 
4577 /*@C
4578    MatGetRowMin - Gets the minimum value (of the real part) of each
4579         row of the matrix
4580 
4581    Logically Collective on Mat
4582 
4583    Input Parameters:
4584 .  mat - the matrix
4585 
4586    Output Parameter:
4587 +  v - the vector for storing the maximums
4588 -  idx - the indices of the column found for each row (optional)
4589 
4590    Level: intermediate
4591 
4592    Notes:
4593     The result of this call are the same as if one converted the matrix to dense format
4594       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4595 
4596     This code is only implemented for a couple of matrix formats.
4597 
4598 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4599           MatGetRowMax()
4600 @*/
4601 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4602 {
4603   PetscErrorCode ierr;
4604 
4605   PetscFunctionBegin;
4606   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4607   PetscValidType(mat,1);
4608   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4609   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4610   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4611   MatCheckPreallocated(mat,1);
4612 
4613   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4614   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4615   PetscFunctionReturn(0);
4616 }
4617 
4618 /*@C
4619    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4620         row of the matrix
4621 
4622    Logically Collective on Mat
4623 
4624    Input Parameters:
4625 .  mat - the matrix
4626 
4627    Output Parameter:
4628 +  v - the vector for storing the minimums
4629 -  idx - the indices of the column found for each row (or NULL if not needed)
4630 
4631    Level: intermediate
4632 
4633    Notes:
4634     if a row is completely empty or has only 0.0 values then the idx[] value for that
4635     row is 0 (the first column).
4636 
4637     This code is only implemented for a couple of matrix formats.
4638 
4639 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4640 @*/
4641 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4642 {
4643   PetscErrorCode ierr;
4644 
4645   PetscFunctionBegin;
4646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4647   PetscValidType(mat,1);
4648   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4649   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4650   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4651   MatCheckPreallocated(mat,1);
4652   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4653 
4654   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4655   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4656   PetscFunctionReturn(0);
4657 }
4658 
4659 /*@C
4660    MatGetRowMax - Gets the maximum value (of the real part) of each
4661         row of the matrix
4662 
4663    Logically Collective on Mat
4664 
4665    Input Parameters:
4666 .  mat - the matrix
4667 
4668    Output Parameter:
4669 +  v - the vector for storing the maximums
4670 -  idx - the indices of the column found for each row (optional)
4671 
4672    Level: intermediate
4673 
4674    Notes:
4675     The result of this call are the same as if one converted the matrix to dense format
4676       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4677 
4678     This code is only implemented for a couple of matrix formats.
4679 
4680 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4681 @*/
4682 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4683 {
4684   PetscErrorCode ierr;
4685 
4686   PetscFunctionBegin;
4687   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4688   PetscValidType(mat,1);
4689   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4690   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4691   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4692   MatCheckPreallocated(mat,1);
4693 
4694   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4695   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4696   PetscFunctionReturn(0);
4697 }
4698 
4699 /*@C
4700    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4701         row of the matrix
4702 
4703    Logically Collective on Mat
4704 
4705    Input Parameters:
4706 .  mat - the matrix
4707 
4708    Output Parameter:
4709 +  v - the vector for storing the maximums
4710 -  idx - the indices of the column found for each row (or NULL if not needed)
4711 
4712    Level: intermediate
4713 
4714    Notes:
4715     if a row is completely empty or has only 0.0 values then the idx[] value for that
4716     row is 0 (the first column).
4717 
4718     This code is only implemented for a couple of matrix formats.
4719 
4720 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4721 @*/
4722 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4723 {
4724   PetscErrorCode ierr;
4725 
4726   PetscFunctionBegin;
4727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4728   PetscValidType(mat,1);
4729   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4730   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4731   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4732   MatCheckPreallocated(mat,1);
4733   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4734 
4735   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4736   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4737   PetscFunctionReturn(0);
4738 }
4739 
4740 /*@
4741    MatGetRowSum - Gets the sum of each row of the matrix
4742 
4743    Logically or Neighborhood Collective on Mat
4744 
4745    Input Parameters:
4746 .  mat - the matrix
4747 
4748    Output Parameter:
4749 .  v - the vector for storing the sum of rows
4750 
4751    Level: intermediate
4752 
4753    Notes:
4754     This code is slow since it is not currently specialized for different formats
4755 
4756 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4757 @*/
4758 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4759 {
4760   Vec            ones;
4761   PetscErrorCode ierr;
4762 
4763   PetscFunctionBegin;
4764   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4765   PetscValidType(mat,1);
4766   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4767   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4768   MatCheckPreallocated(mat,1);
4769   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4770   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4771   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4772   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4773   PetscFunctionReturn(0);
4774 }
4775 
4776 /*@
4777    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4778 
4779    Collective on Mat
4780 
4781    Input Parameter:
4782 +  mat - the matrix to transpose
4783 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4784 
4785    Output Parameters:
4786 .  B - the transpose
4787 
4788    Notes:
4789      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4790 
4791      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4792 
4793      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4794 
4795    Level: intermediate
4796 
4797 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4798 @*/
4799 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4800 {
4801   PetscErrorCode ierr;
4802 
4803   PetscFunctionBegin;
4804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4805   PetscValidType(mat,1);
4806   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4807   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4808   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4809   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4810   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4811   MatCheckPreallocated(mat,1);
4812 
4813   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4814   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4815   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4816   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4817   PetscFunctionReturn(0);
4818 }
4819 
4820 /*@
4821    MatIsTranspose - Test whether a matrix is another one's transpose,
4822         or its own, in which case it tests symmetry.
4823 
4824    Collective on Mat
4825 
4826    Input Parameter:
4827 +  A - the matrix to test
4828 -  B - the matrix to test against, this can equal the first parameter
4829 
4830    Output Parameters:
4831 .  flg - the result
4832 
4833    Notes:
4834    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4835    has a running time of the order of the number of nonzeros; the parallel
4836    test involves parallel copies of the block-offdiagonal parts of the matrix.
4837 
4838    Level: intermediate
4839 
4840 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4841 @*/
4842 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4843 {
4844   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4845 
4846   PetscFunctionBegin;
4847   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4848   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4849   PetscValidBoolPointer(flg,3);
4850   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4851   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4852   *flg = PETSC_FALSE;
4853   if (f && g) {
4854     if (f == g) {
4855       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4856     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4857   } else {
4858     MatType mattype;
4859     if (!f) {
4860       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4861     } else {
4862       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4863     }
4864     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
4865   }
4866   PetscFunctionReturn(0);
4867 }
4868 
4869 /*@
4870    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4871 
4872    Collective on Mat
4873 
4874    Input Parameter:
4875 +  mat - the matrix to transpose and complex conjugate
4876 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4877 
4878    Output Parameters:
4879 .  B - the Hermitian
4880 
4881    Level: intermediate
4882 
4883 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4884 @*/
4885 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4886 {
4887   PetscErrorCode ierr;
4888 
4889   PetscFunctionBegin;
4890   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4891 #if defined(PETSC_USE_COMPLEX)
4892   ierr = MatConjugate(*B);CHKERRQ(ierr);
4893 #endif
4894   PetscFunctionReturn(0);
4895 }
4896 
4897 /*@
4898    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4899 
4900    Collective on Mat
4901 
4902    Input Parameter:
4903 +  A - the matrix to test
4904 -  B - the matrix to test against, this can equal the first parameter
4905 
4906    Output Parameters:
4907 .  flg - the result
4908 
4909    Notes:
4910    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4911    has a running time of the order of the number of nonzeros; the parallel
4912    test involves parallel copies of the block-offdiagonal parts of the matrix.
4913 
4914    Level: intermediate
4915 
4916 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4917 @*/
4918 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4919 {
4920   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4921 
4922   PetscFunctionBegin;
4923   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4924   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4925   PetscValidBoolPointer(flg,3);
4926   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4927   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4928   if (f && g) {
4929     if (f==g) {
4930       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4931     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4932   }
4933   PetscFunctionReturn(0);
4934 }
4935 
4936 /*@
4937    MatPermute - Creates a new matrix with rows and columns permuted from the
4938    original.
4939 
4940    Collective on Mat
4941 
4942    Input Parameters:
4943 +  mat - the matrix to permute
4944 .  row - row permutation, each processor supplies only the permutation for its rows
4945 -  col - column permutation, each processor supplies only the permutation for its columns
4946 
4947    Output Parameters:
4948 .  B - the permuted matrix
4949 
4950    Level: advanced
4951 
4952    Note:
4953    The index sets map from row/col of permuted matrix to row/col of original matrix.
4954    The index sets should be on the same communicator as Mat and have the same local sizes.
4955 
4956 .seealso: MatGetOrdering(), ISAllGather()
4957 
4958 @*/
4959 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4960 {
4961   PetscErrorCode ierr;
4962 
4963   PetscFunctionBegin;
4964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4965   PetscValidType(mat,1);
4966   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4967   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4968   PetscValidPointer(B,4);
4969   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4970   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4971   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4972   MatCheckPreallocated(mat,1);
4973 
4974   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4975   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4976   PetscFunctionReturn(0);
4977 }
4978 
4979 /*@
4980    MatEqual - Compares two matrices.
4981 
4982    Collective on Mat
4983 
4984    Input Parameters:
4985 +  A - the first matrix
4986 -  B - the second matrix
4987 
4988    Output Parameter:
4989 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4990 
4991    Level: intermediate
4992 
4993 @*/
4994 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4995 {
4996   PetscErrorCode ierr;
4997 
4998   PetscFunctionBegin;
4999   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5000   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5001   PetscValidType(A,1);
5002   PetscValidType(B,2);
5003   PetscValidBoolPointer(flg,3);
5004   PetscCheckSameComm(A,1,B,2);
5005   MatCheckPreallocated(B,2);
5006   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5007   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5008   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);
5009   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5010   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5011   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);
5012   MatCheckPreallocated(A,1);
5013 
5014   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5015   PetscFunctionReturn(0);
5016 }
5017 
5018 /*@
5019    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5020    matrices that are stored as vectors.  Either of the two scaling
5021    matrices can be NULL.
5022 
5023    Collective on Mat
5024 
5025    Input Parameters:
5026 +  mat - the matrix to be scaled
5027 .  l - the left scaling vector (or NULL)
5028 -  r - the right scaling vector (or NULL)
5029 
5030    Notes:
5031    MatDiagonalScale() computes A = LAR, where
5032    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5033    The L scales the rows of the matrix, the R scales the columns of the matrix.
5034 
5035    Level: intermediate
5036 
5037 
5038 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5039 @*/
5040 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5041 {
5042   PetscErrorCode ierr;
5043 
5044   PetscFunctionBegin;
5045   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5046   PetscValidType(mat,1);
5047   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5048   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5049   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5050   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5051   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5052   MatCheckPreallocated(mat,1);
5053 
5054   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5055   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5056   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5057   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5058   PetscFunctionReturn(0);
5059 }
5060 
5061 /*@
5062     MatScale - Scales all elements of a matrix by a given number.
5063 
5064     Logically Collective on Mat
5065 
5066     Input Parameters:
5067 +   mat - the matrix to be scaled
5068 -   a  - the scaling value
5069 
5070     Output Parameter:
5071 .   mat - the scaled matrix
5072 
5073     Level: intermediate
5074 
5075 .seealso: MatDiagonalScale()
5076 @*/
5077 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5078 {
5079   PetscErrorCode ierr;
5080 
5081   PetscFunctionBegin;
5082   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5083   PetscValidType(mat,1);
5084   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5085   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5086   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5087   PetscValidLogicalCollectiveScalar(mat,a,2);
5088   MatCheckPreallocated(mat,1);
5089 
5090   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5091   if (a != (PetscScalar)1.0) {
5092     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5093     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5094   }
5095   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5096   PetscFunctionReturn(0);
5097 }
5098 
5099 /*@
5100    MatNorm - Calculates various norms of a matrix.
5101 
5102    Collective on Mat
5103 
5104    Input Parameters:
5105 +  mat - the matrix
5106 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5107 
5108    Output Parameters:
5109 .  nrm - the resulting norm
5110 
5111    Level: intermediate
5112 
5113 @*/
5114 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5115 {
5116   PetscErrorCode ierr;
5117 
5118   PetscFunctionBegin;
5119   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5120   PetscValidType(mat,1);
5121   PetscValidScalarPointer(nrm,3);
5122 
5123   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5124   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5125   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5126   MatCheckPreallocated(mat,1);
5127 
5128   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5129   PetscFunctionReturn(0);
5130 }
5131 
5132 /*
5133      This variable is used to prevent counting of MatAssemblyBegin() that
5134    are called from within a MatAssemblyEnd().
5135 */
5136 static PetscInt MatAssemblyEnd_InUse = 0;
5137 /*@
5138    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5139    be called after completing all calls to MatSetValues().
5140 
5141    Collective on Mat
5142 
5143    Input Parameters:
5144 +  mat - the matrix
5145 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5146 
5147    Notes:
5148    MatSetValues() generally caches the values.  The matrix is ready to
5149    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5150    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5151    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5152    using the matrix.
5153 
5154    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5155    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
5156    a global collective operation requring all processes that share the matrix.
5157 
5158    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5159    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5160    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5161 
5162    Level: beginner
5163 
5164 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5165 @*/
5166 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5167 {
5168   PetscErrorCode ierr;
5169 
5170   PetscFunctionBegin;
5171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5172   PetscValidType(mat,1);
5173   MatCheckPreallocated(mat,1);
5174   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5175   if (mat->assembled) {
5176     mat->was_assembled = PETSC_TRUE;
5177     mat->assembled     = PETSC_FALSE;
5178   }
5179 
5180   if (!MatAssemblyEnd_InUse) {
5181     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5182     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5183     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5184   } else if (mat->ops->assemblybegin) {
5185     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5186   }
5187   PetscFunctionReturn(0);
5188 }
5189 
5190 /*@
5191    MatAssembled - Indicates if a matrix has been assembled and is ready for
5192      use; for example, in matrix-vector product.
5193 
5194    Not Collective
5195 
5196    Input Parameter:
5197 .  mat - the matrix
5198 
5199    Output Parameter:
5200 .  assembled - PETSC_TRUE or PETSC_FALSE
5201 
5202    Level: advanced
5203 
5204 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5205 @*/
5206 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5207 {
5208   PetscFunctionBegin;
5209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5210   PetscValidPointer(assembled,2);
5211   *assembled = mat->assembled;
5212   PetscFunctionReturn(0);
5213 }
5214 
5215 /*@
5216    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5217    be called after MatAssemblyBegin().
5218 
5219    Collective on Mat
5220 
5221    Input Parameters:
5222 +  mat - the matrix
5223 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5224 
5225    Options Database Keys:
5226 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5227 .  -mat_view ::ascii_info_detail - Prints more detailed info
5228 .  -mat_view - Prints matrix in ASCII format
5229 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5230 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5231 .  -display <name> - Sets display name (default is host)
5232 .  -draw_pause <sec> - Sets number of seconds to pause after display
5233 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5234 .  -viewer_socket_machine <machine> - Machine to use for socket
5235 .  -viewer_socket_port <port> - Port number to use for socket
5236 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5237 
5238    Notes:
5239    MatSetValues() generally caches the values.  The matrix is ready to
5240    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5241    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5242    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5243    using the matrix.
5244 
5245    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5246    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5247    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5248 
5249    Level: beginner
5250 
5251 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5252 @*/
5253 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5254 {
5255   PetscErrorCode  ierr;
5256   static PetscInt inassm = 0;
5257   PetscBool       flg    = PETSC_FALSE;
5258 
5259   PetscFunctionBegin;
5260   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5261   PetscValidType(mat,1);
5262 
5263   inassm++;
5264   MatAssemblyEnd_InUse++;
5265   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5266     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5267     if (mat->ops->assemblyend) {
5268       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5269     }
5270     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5271   } else if (mat->ops->assemblyend) {
5272     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5273   }
5274 
5275   /* Flush assembly is not a true assembly */
5276   if (type != MAT_FLUSH_ASSEMBLY) {
5277     mat->num_ass++;
5278     mat->assembled        = PETSC_TRUE;
5279     mat->ass_nonzerostate = mat->nonzerostate;
5280   }
5281 
5282   mat->insertmode = NOT_SET_VALUES;
5283   MatAssemblyEnd_InUse--;
5284   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5285   if (!mat->symmetric_eternal) {
5286     mat->symmetric_set              = PETSC_FALSE;
5287     mat->hermitian_set              = PETSC_FALSE;
5288     mat->structurally_symmetric_set = PETSC_FALSE;
5289   }
5290   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5291     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5292 
5293     if (mat->checksymmetryonassembly) {
5294       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5295       if (flg) {
5296         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5297       } else {
5298         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5299       }
5300     }
5301     if (mat->nullsp && mat->checknullspaceonassembly) {
5302       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5303     }
5304   }
5305   inassm--;
5306   PetscFunctionReturn(0);
5307 }
5308 
5309 /*@
5310    MatSetOption - Sets a parameter option for a matrix. Some options
5311    may be specific to certain storage formats.  Some options
5312    determine how values will be inserted (or added). Sorted,
5313    row-oriented input will generally assemble the fastest. The default
5314    is row-oriented.
5315 
5316    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5317 
5318    Input Parameters:
5319 +  mat - the matrix
5320 .  option - the option, one of those listed below (and possibly others),
5321 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5322 
5323   Options Describing Matrix Structure:
5324 +    MAT_SPD - symmetric positive definite
5325 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5326 .    MAT_HERMITIAN - transpose is the complex conjugation
5327 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5328 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5329                             you set to be kept with all future use of the matrix
5330                             including after MatAssemblyBegin/End() which could
5331                             potentially change the symmetry structure, i.e. you
5332                             KNOW the matrix will ALWAYS have the property you set.
5333 
5334 
5335    Options For Use with MatSetValues():
5336    Insert a logically dense subblock, which can be
5337 .    MAT_ROW_ORIENTED - row-oriented (default)
5338 
5339    Note these options reflect the data you pass in with MatSetValues(); it has
5340    nothing to do with how the data is stored internally in the matrix
5341    data structure.
5342 
5343    When (re)assembling a matrix, we can restrict the input for
5344    efficiency/debugging purposes.  These options include:
5345 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5346 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5347 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5348 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5349 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5350 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5351         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5352         performance for very large process counts.
5353 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5354         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5355         functions, instead sending only neighbor messages.
5356 
5357    Notes:
5358    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5359 
5360    Some options are relevant only for particular matrix types and
5361    are thus ignored by others.  Other options are not supported by
5362    certain matrix types and will generate an error message if set.
5363 
5364    If using a Fortran 77 module to compute a matrix, one may need to
5365    use the column-oriented option (or convert to the row-oriented
5366    format).
5367 
5368    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5369    that would generate a new entry in the nonzero structure is instead
5370    ignored.  Thus, if memory has not alredy been allocated for this particular
5371    data, then the insertion is ignored. For dense matrices, in which
5372    the entire array is allocated, no entries are ever ignored.
5373    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5374 
5375    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5376    that would generate a new entry in the nonzero structure instead produces
5377    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
5378 
5379    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5380    that would generate a new entry that has not been preallocated will
5381    instead produce an error. (Currently supported for AIJ and BAIJ formats
5382    only.) This is a useful flag when debugging matrix memory preallocation.
5383    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5384 
5385    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5386    other processors should be dropped, rather than stashed.
5387    This is useful if you know that the "owning" processor is also
5388    always generating the correct matrix entries, so that PETSc need
5389    not transfer duplicate entries generated on another processor.
5390 
5391    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5392    searches during matrix assembly. When this flag is set, the hash table
5393    is created during the first Matrix Assembly. This hash table is
5394    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5395    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5396    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5397    supported by MATMPIBAIJ format only.
5398 
5399    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5400    are kept in the nonzero structure
5401 
5402    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5403    a zero location in the matrix
5404 
5405    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5406 
5407    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5408         zero row routines and thus improves performance for very large process counts.
5409 
5410    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5411         part of the matrix (since they should match the upper triangular part).
5412 
5413    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5414                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5415                      with finite difference schemes with non-periodic boundary conditions.
5416    Notes:
5417     Can only be called after MatSetSizes() and MatSetType() have been set.
5418 
5419    Level: intermediate
5420 
5421 .seealso:  MatOption, Mat
5422 
5423 @*/
5424 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5425 {
5426   PetscErrorCode ierr;
5427 
5428   PetscFunctionBegin;
5429   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5430   PetscValidType(mat,1);
5431   if (op > 0) {
5432     PetscValidLogicalCollectiveEnum(mat,op,2);
5433     PetscValidLogicalCollectiveBool(mat,flg,3);
5434   }
5435 
5436   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);
5437   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()");
5438 
5439   switch (op) {
5440   case MAT_NO_OFF_PROC_ENTRIES:
5441     mat->nooffprocentries = flg;
5442     PetscFunctionReturn(0);
5443     break;
5444   case MAT_SUBSET_OFF_PROC_ENTRIES:
5445     mat->assembly_subset = flg;
5446     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5447 #if !defined(PETSC_HAVE_MPIUNI)
5448       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5449 #endif
5450       mat->stash.first_assembly_done = PETSC_FALSE;
5451     }
5452     PetscFunctionReturn(0);
5453   case MAT_NO_OFF_PROC_ZERO_ROWS:
5454     mat->nooffproczerorows = flg;
5455     PetscFunctionReturn(0);
5456     break;
5457   case MAT_SPD:
5458     mat->spd_set = PETSC_TRUE;
5459     mat->spd     = flg;
5460     if (flg) {
5461       mat->symmetric                  = PETSC_TRUE;
5462       mat->structurally_symmetric     = PETSC_TRUE;
5463       mat->symmetric_set              = PETSC_TRUE;
5464       mat->structurally_symmetric_set = PETSC_TRUE;
5465     }
5466     break;
5467   case MAT_SYMMETRIC:
5468     mat->symmetric = flg;
5469     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5470     mat->symmetric_set              = PETSC_TRUE;
5471     mat->structurally_symmetric_set = flg;
5472 #if !defined(PETSC_USE_COMPLEX)
5473     mat->hermitian     = flg;
5474     mat->hermitian_set = PETSC_TRUE;
5475 #endif
5476     break;
5477   case MAT_HERMITIAN:
5478     mat->hermitian = flg;
5479     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5480     mat->hermitian_set              = PETSC_TRUE;
5481     mat->structurally_symmetric_set = flg;
5482 #if !defined(PETSC_USE_COMPLEX)
5483     mat->symmetric     = flg;
5484     mat->symmetric_set = PETSC_TRUE;
5485 #endif
5486     break;
5487   case MAT_STRUCTURALLY_SYMMETRIC:
5488     mat->structurally_symmetric     = flg;
5489     mat->structurally_symmetric_set = PETSC_TRUE;
5490     break;
5491   case MAT_SYMMETRY_ETERNAL:
5492     mat->symmetric_eternal = flg;
5493     break;
5494   case MAT_STRUCTURE_ONLY:
5495     mat->structure_only = flg;
5496     break;
5497   case MAT_SORTED_FULL:
5498     mat->sortedfull = flg;
5499     break;
5500   default:
5501     break;
5502   }
5503   if (mat->ops->setoption) {
5504     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5505   }
5506   PetscFunctionReturn(0);
5507 }
5508 
5509 /*@
5510    MatGetOption - Gets a parameter option that has been set for a matrix.
5511 
5512    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5513 
5514    Input Parameters:
5515 +  mat - the matrix
5516 -  option - the option, this only responds to certain options, check the code for which ones
5517 
5518    Output Parameter:
5519 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5520 
5521     Notes:
5522     Can only be called after MatSetSizes() and MatSetType() have been set.
5523 
5524    Level: intermediate
5525 
5526 .seealso:  MatOption, MatSetOption()
5527 
5528 @*/
5529 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5530 {
5531   PetscFunctionBegin;
5532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5533   PetscValidType(mat,1);
5534 
5535   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);
5536   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()");
5537 
5538   switch (op) {
5539   case MAT_NO_OFF_PROC_ENTRIES:
5540     *flg = mat->nooffprocentries;
5541     break;
5542   case MAT_NO_OFF_PROC_ZERO_ROWS:
5543     *flg = mat->nooffproczerorows;
5544     break;
5545   case MAT_SYMMETRIC:
5546     *flg = mat->symmetric;
5547     break;
5548   case MAT_HERMITIAN:
5549     *flg = mat->hermitian;
5550     break;
5551   case MAT_STRUCTURALLY_SYMMETRIC:
5552     *flg = mat->structurally_symmetric;
5553     break;
5554   case MAT_SYMMETRY_ETERNAL:
5555     *flg = mat->symmetric_eternal;
5556     break;
5557   case MAT_SPD:
5558     *flg = mat->spd;
5559     break;
5560   default:
5561     break;
5562   }
5563   PetscFunctionReturn(0);
5564 }
5565 
5566 /*@
5567    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5568    this routine retains the old nonzero structure.
5569 
5570    Logically Collective on Mat
5571 
5572    Input Parameters:
5573 .  mat - the matrix
5574 
5575    Level: intermediate
5576 
5577    Notes:
5578     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.
5579    See the Performance chapter of the users manual for information on preallocating matrices.
5580 
5581 .seealso: MatZeroRows()
5582 @*/
5583 PetscErrorCode MatZeroEntries(Mat mat)
5584 {
5585   PetscErrorCode ierr;
5586 
5587   PetscFunctionBegin;
5588   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5589   PetscValidType(mat,1);
5590   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5591   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");
5592   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5593   MatCheckPreallocated(mat,1);
5594 
5595   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5596   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5597   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5598   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5599   PetscFunctionReturn(0);
5600 }
5601 
5602 /*@
5603    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5604    of a set of rows and columns of a matrix.
5605 
5606    Collective on Mat
5607 
5608    Input Parameters:
5609 +  mat - the matrix
5610 .  numRows - the number of rows to remove
5611 .  rows - the global row indices
5612 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5613 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5614 -  b - optional vector of right hand side, that will be adjusted by provided solution
5615 
5616    Notes:
5617    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5618 
5619    The user can set a value in the diagonal entry (or for the AIJ and
5620    row formats can optionally remove the main diagonal entry from the
5621    nonzero structure as well, by passing 0.0 as the final argument).
5622 
5623    For the parallel case, all processes that share the matrix (i.e.,
5624    those in the communicator used for matrix creation) MUST call this
5625    routine, regardless of whether any rows being zeroed are owned by
5626    them.
5627 
5628    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5629    list only rows local to itself).
5630 
5631    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5632 
5633    Level: intermediate
5634 
5635 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5636           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5637 @*/
5638 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5639 {
5640   PetscErrorCode ierr;
5641 
5642   PetscFunctionBegin;
5643   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5644   PetscValidType(mat,1);
5645   if (numRows) PetscValidIntPointer(rows,3);
5646   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5647   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5648   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5649   MatCheckPreallocated(mat,1);
5650 
5651   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5652   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5653   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5654   PetscFunctionReturn(0);
5655 }
5656 
5657 /*@
5658    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5659    of a set of rows and columns of a matrix.
5660 
5661    Collective on Mat
5662 
5663    Input Parameters:
5664 +  mat - the matrix
5665 .  is - the rows to zero
5666 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5667 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5668 -  b - optional vector of right hand side, that will be adjusted by provided solution
5669 
5670    Notes:
5671    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5672 
5673    The user can set a value in the diagonal entry (or for the AIJ and
5674    row formats can optionally remove the main diagonal entry from the
5675    nonzero structure as well, by passing 0.0 as the final argument).
5676 
5677    For the parallel case, all processes that share the matrix (i.e.,
5678    those in the communicator used for matrix creation) MUST call this
5679    routine, regardless of whether any rows being zeroed are owned by
5680    them.
5681 
5682    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5683    list only rows local to itself).
5684 
5685    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5686 
5687    Level: intermediate
5688 
5689 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5690           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5691 @*/
5692 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5693 {
5694   PetscErrorCode ierr;
5695   PetscInt       numRows;
5696   const PetscInt *rows;
5697 
5698   PetscFunctionBegin;
5699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5700   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5701   PetscValidType(mat,1);
5702   PetscValidType(is,2);
5703   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5704   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5705   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5706   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5707   PetscFunctionReturn(0);
5708 }
5709 
5710 /*@
5711    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5712    of a set of rows of a matrix.
5713 
5714    Collective on Mat
5715 
5716    Input Parameters:
5717 +  mat - the matrix
5718 .  numRows - the number of rows to remove
5719 .  rows - the global row indices
5720 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5721 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5722 -  b - optional vector of right hand side, that will be adjusted by provided solution
5723 
5724    Notes:
5725    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5726    but does not release memory.  For the dense and block diagonal
5727    formats this does not alter the nonzero structure.
5728 
5729    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5730    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5731    merely zeroed.
5732 
5733    The user can set a value in the diagonal entry (or for the AIJ and
5734    row formats can optionally remove the main diagonal entry from the
5735    nonzero structure as well, by passing 0.0 as the final argument).
5736 
5737    For the parallel case, all processes that share the matrix (i.e.,
5738    those in the communicator used for matrix creation) MUST call this
5739    routine, regardless of whether any rows being zeroed are owned by
5740    them.
5741 
5742    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5743    list only rows local to itself).
5744 
5745    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5746    owns that are to be zeroed. This saves a global synchronization in the implementation.
5747 
5748    Level: intermediate
5749 
5750 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5751           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5752 @*/
5753 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5754 {
5755   PetscErrorCode ierr;
5756 
5757   PetscFunctionBegin;
5758   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5759   PetscValidType(mat,1);
5760   if (numRows) PetscValidIntPointer(rows,3);
5761   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5762   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5763   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5764   MatCheckPreallocated(mat,1);
5765 
5766   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5767   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5768   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5769   PetscFunctionReturn(0);
5770 }
5771 
5772 /*@
5773    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5774    of a set of rows of a matrix.
5775 
5776    Collective on Mat
5777 
5778    Input Parameters:
5779 +  mat - the matrix
5780 .  is - index set of rows to remove
5781 .  diag - value put in all diagonals of eliminated rows
5782 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5783 -  b - optional vector of right hand side, that will be adjusted by provided solution
5784 
5785    Notes:
5786    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5787    but does not release memory.  For the dense and block diagonal
5788    formats this does not alter the nonzero structure.
5789 
5790    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5791    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5792    merely zeroed.
5793 
5794    The user can set a value in the diagonal entry (or for the AIJ and
5795    row formats can optionally remove the main diagonal entry from the
5796    nonzero structure as well, by passing 0.0 as the final argument).
5797 
5798    For the parallel case, all processes that share the matrix (i.e.,
5799    those in the communicator used for matrix creation) MUST call this
5800    routine, regardless of whether any rows being zeroed are owned by
5801    them.
5802 
5803    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5804    list only rows local to itself).
5805 
5806    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5807    owns that are to be zeroed. This saves a global synchronization in the implementation.
5808 
5809    Level: intermediate
5810 
5811 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5812           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5813 @*/
5814 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5815 {
5816   PetscInt       numRows;
5817   const PetscInt *rows;
5818   PetscErrorCode ierr;
5819 
5820   PetscFunctionBegin;
5821   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5822   PetscValidType(mat,1);
5823   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5824   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5825   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5826   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5827   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5828   PetscFunctionReturn(0);
5829 }
5830 
5831 /*@
5832    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5833    of a set of rows of a matrix. These rows must be local to the process.
5834 
5835    Collective on Mat
5836 
5837    Input Parameters:
5838 +  mat - the matrix
5839 .  numRows - the number of rows to remove
5840 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5841 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5842 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5843 -  b - optional vector of right hand side, that will be adjusted by provided solution
5844 
5845    Notes:
5846    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5847    but does not release memory.  For the dense and block diagonal
5848    formats this does not alter the nonzero structure.
5849 
5850    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5851    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5852    merely zeroed.
5853 
5854    The user can set a value in the diagonal entry (or for the AIJ and
5855    row formats can optionally remove the main diagonal entry from the
5856    nonzero structure as well, by passing 0.0 as the final argument).
5857 
5858    For the parallel case, all processes that share the matrix (i.e.,
5859    those in the communicator used for matrix creation) MUST call this
5860    routine, regardless of whether any rows being zeroed are owned by
5861    them.
5862 
5863    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5864    list only rows local to itself).
5865 
5866    The grid coordinates are across the entire grid, not just the local portion
5867 
5868    In Fortran idxm and idxn should be declared as
5869 $     MatStencil idxm(4,m)
5870    and the values inserted using
5871 $    idxm(MatStencil_i,1) = i
5872 $    idxm(MatStencil_j,1) = j
5873 $    idxm(MatStencil_k,1) = k
5874 $    idxm(MatStencil_c,1) = c
5875    etc
5876 
5877    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5878    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5879    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5880    DM_BOUNDARY_PERIODIC boundary type.
5881 
5882    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
5883    a single value per point) you can skip filling those indices.
5884 
5885    Level: intermediate
5886 
5887 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5888           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5889 @*/
5890 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5891 {
5892   PetscInt       dim     = mat->stencil.dim;
5893   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5894   PetscInt       *dims   = mat->stencil.dims+1;
5895   PetscInt       *starts = mat->stencil.starts;
5896   PetscInt       *dxm    = (PetscInt*) rows;
5897   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5898   PetscErrorCode ierr;
5899 
5900   PetscFunctionBegin;
5901   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5902   PetscValidType(mat,1);
5903   if (numRows) PetscValidIntPointer(rows,3);
5904 
5905   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5906   for (i = 0; i < numRows; ++i) {
5907     /* Skip unused dimensions (they are ordered k, j, i, c) */
5908     for (j = 0; j < 3-sdim; ++j) dxm++;
5909     /* Local index in X dir */
5910     tmp = *dxm++ - starts[0];
5911     /* Loop over remaining dimensions */
5912     for (j = 0; j < dim-1; ++j) {
5913       /* If nonlocal, set index to be negative */
5914       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5915       /* Update local index */
5916       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5917     }
5918     /* Skip component slot if necessary */
5919     if (mat->stencil.noc) dxm++;
5920     /* Local row number */
5921     if (tmp >= 0) {
5922       jdxm[numNewRows++] = tmp;
5923     }
5924   }
5925   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5926   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5927   PetscFunctionReturn(0);
5928 }
5929 
5930 /*@
5931    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5932    of a set of rows and columns of a matrix.
5933 
5934    Collective on Mat
5935 
5936    Input Parameters:
5937 +  mat - the matrix
5938 .  numRows - the number of rows/columns to remove
5939 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5940 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5941 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5942 -  b - optional vector of right hand side, that will be adjusted by provided solution
5943 
5944    Notes:
5945    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5946    but does not release memory.  For the dense and block diagonal
5947    formats this does not alter the nonzero structure.
5948 
5949    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5950    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5951    merely zeroed.
5952 
5953    The user can set a value in the diagonal entry (or for the AIJ and
5954    row formats can optionally remove the main diagonal entry from the
5955    nonzero structure as well, by passing 0.0 as the final argument).
5956 
5957    For the parallel case, all processes that share the matrix (i.e.,
5958    those in the communicator used for matrix creation) MUST call this
5959    routine, regardless of whether any rows being zeroed are owned by
5960    them.
5961 
5962    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5963    list only rows local to itself, but the row/column numbers are given in local numbering).
5964 
5965    The grid coordinates are across the entire grid, not just the local portion
5966 
5967    In Fortran idxm and idxn should be declared as
5968 $     MatStencil idxm(4,m)
5969    and the values inserted using
5970 $    idxm(MatStencil_i,1) = i
5971 $    idxm(MatStencil_j,1) = j
5972 $    idxm(MatStencil_k,1) = k
5973 $    idxm(MatStencil_c,1) = c
5974    etc
5975 
5976    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5977    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5978    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5979    DM_BOUNDARY_PERIODIC boundary type.
5980 
5981    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
5982    a single value per point) you can skip filling those indices.
5983 
5984    Level: intermediate
5985 
5986 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5987           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5988 @*/
5989 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5990 {
5991   PetscInt       dim     = mat->stencil.dim;
5992   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5993   PetscInt       *dims   = mat->stencil.dims+1;
5994   PetscInt       *starts = mat->stencil.starts;
5995   PetscInt       *dxm    = (PetscInt*) rows;
5996   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5997   PetscErrorCode ierr;
5998 
5999   PetscFunctionBegin;
6000   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6001   PetscValidType(mat,1);
6002   if (numRows) PetscValidIntPointer(rows,3);
6003 
6004   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6005   for (i = 0; i < numRows; ++i) {
6006     /* Skip unused dimensions (they are ordered k, j, i, c) */
6007     for (j = 0; j < 3-sdim; ++j) dxm++;
6008     /* Local index in X dir */
6009     tmp = *dxm++ - starts[0];
6010     /* Loop over remaining dimensions */
6011     for (j = 0; j < dim-1; ++j) {
6012       /* If nonlocal, set index to be negative */
6013       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6014       /* Update local index */
6015       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6016     }
6017     /* Skip component slot if necessary */
6018     if (mat->stencil.noc) dxm++;
6019     /* Local row number */
6020     if (tmp >= 0) {
6021       jdxm[numNewRows++] = tmp;
6022     }
6023   }
6024   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6025   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6026   PetscFunctionReturn(0);
6027 }
6028 
6029 /*@C
6030    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6031    of a set of rows of a matrix; using local numbering of rows.
6032 
6033    Collective on Mat
6034 
6035    Input Parameters:
6036 +  mat - the matrix
6037 .  numRows - the number of rows to remove
6038 .  rows - the global row indices
6039 .  diag - value put in all diagonals of eliminated rows
6040 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6041 -  b - optional vector of right hand side, that will be adjusted by provided solution
6042 
6043    Notes:
6044    Before calling MatZeroRowsLocal(), the user must first set the
6045    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6046 
6047    For the AIJ matrix formats this removes the old nonzero structure,
6048    but does not release memory.  For the dense and block diagonal
6049    formats this does not alter the nonzero structure.
6050 
6051    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6052    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6053    merely zeroed.
6054 
6055    The user can set a value in the diagonal entry (or for the AIJ and
6056    row formats can optionally remove the main diagonal entry from the
6057    nonzero structure as well, by passing 0.0 as the final argument).
6058 
6059    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6060    owns that are to be zeroed. This saves a global synchronization in the implementation.
6061 
6062    Level: intermediate
6063 
6064 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6065           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6066 @*/
6067 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6068 {
6069   PetscErrorCode ierr;
6070 
6071   PetscFunctionBegin;
6072   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6073   PetscValidType(mat,1);
6074   if (numRows) PetscValidIntPointer(rows,3);
6075   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6076   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6077   MatCheckPreallocated(mat,1);
6078 
6079   if (mat->ops->zerorowslocal) {
6080     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6081   } else {
6082     IS             is, newis;
6083     const PetscInt *newRows;
6084 
6085     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6086     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6087     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6088     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6089     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6090     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6091     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6092     ierr = ISDestroy(&is);CHKERRQ(ierr);
6093   }
6094   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6095   PetscFunctionReturn(0);
6096 }
6097 
6098 /*@
6099    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6100    of a set of rows of a matrix; using local numbering of rows.
6101 
6102    Collective on Mat
6103 
6104    Input Parameters:
6105 +  mat - the matrix
6106 .  is - index set of rows to remove
6107 .  diag - value put in all diagonals of eliminated rows
6108 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6109 -  b - optional vector of right hand side, that will be adjusted by provided solution
6110 
6111    Notes:
6112    Before calling MatZeroRowsLocalIS(), the user must first set the
6113    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6114 
6115    For the AIJ matrix formats this removes the old nonzero structure,
6116    but does not release memory.  For the dense and block diagonal
6117    formats this does not alter the nonzero structure.
6118 
6119    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6120    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6121    merely zeroed.
6122 
6123    The user can set a value in the diagonal entry (or for the AIJ and
6124    row formats can optionally remove the main diagonal entry from the
6125    nonzero structure as well, by passing 0.0 as the final argument).
6126 
6127    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6128    owns that are to be zeroed. This saves a global synchronization in the implementation.
6129 
6130    Level: intermediate
6131 
6132 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6133           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6134 @*/
6135 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6136 {
6137   PetscErrorCode ierr;
6138   PetscInt       numRows;
6139   const PetscInt *rows;
6140 
6141   PetscFunctionBegin;
6142   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6143   PetscValidType(mat,1);
6144   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6145   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6146   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6147   MatCheckPreallocated(mat,1);
6148 
6149   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6150   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6151   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6152   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6153   PetscFunctionReturn(0);
6154 }
6155 
6156 /*@
6157    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6158    of a set of rows and columns of a matrix; using local numbering of rows.
6159 
6160    Collective on Mat
6161 
6162    Input Parameters:
6163 +  mat - the matrix
6164 .  numRows - the number of rows to remove
6165 .  rows - the global row indices
6166 .  diag - value put in all diagonals of eliminated rows
6167 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6168 -  b - optional vector of right hand side, that will be adjusted by provided solution
6169 
6170    Notes:
6171    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6172    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6173 
6174    The user can set a value in the diagonal entry (or for the AIJ and
6175    row formats can optionally remove the main diagonal entry from the
6176    nonzero structure as well, by passing 0.0 as the final argument).
6177 
6178    Level: intermediate
6179 
6180 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6181           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6182 @*/
6183 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6184 {
6185   PetscErrorCode ierr;
6186   IS             is, newis;
6187   const PetscInt *newRows;
6188 
6189   PetscFunctionBegin;
6190   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6191   PetscValidType(mat,1);
6192   if (numRows) PetscValidIntPointer(rows,3);
6193   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6194   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6195   MatCheckPreallocated(mat,1);
6196 
6197   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6198   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6199   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6200   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6201   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6202   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6203   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6204   ierr = ISDestroy(&is);CHKERRQ(ierr);
6205   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6206   PetscFunctionReturn(0);
6207 }
6208 
6209 /*@
6210    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6211    of a set of rows and columns of a matrix; using local numbering of rows.
6212 
6213    Collective on Mat
6214 
6215    Input Parameters:
6216 +  mat - the matrix
6217 .  is - index set of rows to remove
6218 .  diag - value put in all diagonals of eliminated rows
6219 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6220 -  b - optional vector of right hand side, that will be adjusted by provided solution
6221 
6222    Notes:
6223    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6224    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6225 
6226    The user can set a value in the diagonal entry (or for the AIJ and
6227    row formats can optionally remove the main diagonal entry from the
6228    nonzero structure as well, by passing 0.0 as the final argument).
6229 
6230    Level: intermediate
6231 
6232 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6233           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6234 @*/
6235 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6236 {
6237   PetscErrorCode ierr;
6238   PetscInt       numRows;
6239   const PetscInt *rows;
6240 
6241   PetscFunctionBegin;
6242   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6243   PetscValidType(mat,1);
6244   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6245   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6246   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6247   MatCheckPreallocated(mat,1);
6248 
6249   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6250   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6251   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6252   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6253   PetscFunctionReturn(0);
6254 }
6255 
6256 /*@C
6257    MatGetSize - Returns the numbers of rows and columns in a matrix.
6258 
6259    Not Collective
6260 
6261    Input Parameter:
6262 .  mat - the matrix
6263 
6264    Output Parameters:
6265 +  m - the number of global rows
6266 -  n - the number of global columns
6267 
6268    Note: both output parameters can be NULL on input.
6269 
6270    Level: beginner
6271 
6272 .seealso: MatGetLocalSize()
6273 @*/
6274 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6275 {
6276   PetscFunctionBegin;
6277   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6278   if (m) *m = mat->rmap->N;
6279   if (n) *n = mat->cmap->N;
6280   PetscFunctionReturn(0);
6281 }
6282 
6283 /*@C
6284    MatGetLocalSize - Returns the number of rows and columns in a matrix
6285    stored locally.  This information may be implementation dependent, so
6286    use with care.
6287 
6288    Not Collective
6289 
6290    Input Parameters:
6291 .  mat - the matrix
6292 
6293    Output Parameters:
6294 +  m - the number of local rows
6295 -  n - the number of local columns
6296 
6297    Note: both output parameters can be NULL on input.
6298 
6299    Level: beginner
6300 
6301 .seealso: MatGetSize()
6302 @*/
6303 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6304 {
6305   PetscFunctionBegin;
6306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6307   if (m) PetscValidIntPointer(m,2);
6308   if (n) PetscValidIntPointer(n,3);
6309   if (m) *m = mat->rmap->n;
6310   if (n) *n = mat->cmap->n;
6311   PetscFunctionReturn(0);
6312 }
6313 
6314 /*@C
6315    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6316    this processor. (The columns of the "diagonal block")
6317 
6318    Not Collective, unless matrix has not been allocated, then collective on Mat
6319 
6320    Input Parameters:
6321 .  mat - the matrix
6322 
6323    Output Parameters:
6324 +  m - the global index of the first local column
6325 -  n - one more than the global index of the last local column
6326 
6327    Notes:
6328     both output parameters can be NULL on input.
6329 
6330    Level: developer
6331 
6332 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6333 
6334 @*/
6335 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6336 {
6337   PetscFunctionBegin;
6338   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6339   PetscValidType(mat,1);
6340   if (m) PetscValidIntPointer(m,2);
6341   if (n) PetscValidIntPointer(n,3);
6342   MatCheckPreallocated(mat,1);
6343   if (m) *m = mat->cmap->rstart;
6344   if (n) *n = mat->cmap->rend;
6345   PetscFunctionReturn(0);
6346 }
6347 
6348 /*@C
6349    MatGetOwnershipRange - Returns the range of matrix rows owned by
6350    this processor, assuming that the matrix is laid out with the first
6351    n1 rows on the first processor, the next n2 rows on the second, etc.
6352    For certain parallel layouts this range may not be well defined.
6353 
6354    Not Collective
6355 
6356    Input Parameters:
6357 .  mat - the matrix
6358 
6359    Output Parameters:
6360 +  m - the global index of the first local row
6361 -  n - one more than the global index of the last local row
6362 
6363    Note: Both output parameters can be NULL on input.
6364 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6365 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6366 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6367 
6368    Level: beginner
6369 
6370 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6371 
6372 @*/
6373 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6374 {
6375   PetscFunctionBegin;
6376   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6377   PetscValidType(mat,1);
6378   if (m) PetscValidIntPointer(m,2);
6379   if (n) PetscValidIntPointer(n,3);
6380   MatCheckPreallocated(mat,1);
6381   if (m) *m = mat->rmap->rstart;
6382   if (n) *n = mat->rmap->rend;
6383   PetscFunctionReturn(0);
6384 }
6385 
6386 /*@C
6387    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6388    each process
6389 
6390    Not Collective, unless matrix has not been allocated, then collective on Mat
6391 
6392    Input Parameters:
6393 .  mat - the matrix
6394 
6395    Output Parameters:
6396 .  ranges - start of each processors portion plus one more than the total length at the end
6397 
6398    Level: beginner
6399 
6400 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6401 
6402 @*/
6403 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6404 {
6405   PetscErrorCode ierr;
6406 
6407   PetscFunctionBegin;
6408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6409   PetscValidType(mat,1);
6410   MatCheckPreallocated(mat,1);
6411   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6412   PetscFunctionReturn(0);
6413 }
6414 
6415 /*@C
6416    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6417    this processor. (The columns of the "diagonal blocks" for each process)
6418 
6419    Not Collective, unless matrix has not been allocated, then collective on Mat
6420 
6421    Input Parameters:
6422 .  mat - the matrix
6423 
6424    Output Parameters:
6425 .  ranges - start of each processors portion plus one more then the total length at the end
6426 
6427    Level: beginner
6428 
6429 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6430 
6431 @*/
6432 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6433 {
6434   PetscErrorCode ierr;
6435 
6436   PetscFunctionBegin;
6437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6438   PetscValidType(mat,1);
6439   MatCheckPreallocated(mat,1);
6440   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6441   PetscFunctionReturn(0);
6442 }
6443 
6444 /*@C
6445    MatGetOwnershipIS - Get row and column ownership as index sets
6446 
6447    Not Collective
6448 
6449    Input Arguments:
6450 .  A - matrix of type Elemental
6451 
6452    Output Arguments:
6453 +  rows - rows in which this process owns elements
6454 -  cols - columns in which this process owns elements
6455 
6456    Level: intermediate
6457 
6458 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6459 @*/
6460 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6461 {
6462   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6463 
6464   PetscFunctionBegin;
6465   MatCheckPreallocated(A,1);
6466   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6467   if (f) {
6468     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6469   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6470     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6471     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6472   }
6473   PetscFunctionReturn(0);
6474 }
6475 
6476 /*@C
6477    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6478    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6479    to complete the factorization.
6480 
6481    Collective on Mat
6482 
6483    Input Parameters:
6484 +  mat - the matrix
6485 .  row - row permutation
6486 .  column - column permutation
6487 -  info - structure containing
6488 $      levels - number of levels of fill.
6489 $      expected fill - as ratio of original fill.
6490 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6491                 missing diagonal entries)
6492 
6493    Output Parameters:
6494 .  fact - new matrix that has been symbolically factored
6495 
6496    Notes:
6497     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6498 
6499    Most users should employ the simplified KSP interface for linear solvers
6500    instead of working directly with matrix algebra routines such as this.
6501    See, e.g., KSPCreate().
6502 
6503    Level: developer
6504 
6505 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6506           MatGetOrdering(), MatFactorInfo
6507 
6508     Note: this uses the definition of level of fill as in Y. Saad, 2003
6509 
6510     Developer Note: fortran interface is not autogenerated as the f90
6511     interface defintion cannot be generated correctly [due to MatFactorInfo]
6512 
6513    References:
6514      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6515 @*/
6516 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6517 {
6518   PetscErrorCode ierr;
6519 
6520   PetscFunctionBegin;
6521   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6522   PetscValidType(mat,1);
6523   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6524   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6525   PetscValidPointer(info,4);
6526   PetscValidPointer(fact,5);
6527   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6528   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6529   if (!(fact)->ops->ilufactorsymbolic) {
6530     MatSolverType spackage;
6531     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6532     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6533   }
6534   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6535   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6536   MatCheckPreallocated(mat,2);
6537 
6538   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6539   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6540   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6541   PetscFunctionReturn(0);
6542 }
6543 
6544 /*@C
6545    MatICCFactorSymbolic - Performs symbolic incomplete
6546    Cholesky factorization for a symmetric matrix.  Use
6547    MatCholeskyFactorNumeric() to complete the factorization.
6548 
6549    Collective on Mat
6550 
6551    Input Parameters:
6552 +  mat - the matrix
6553 .  perm - row and column permutation
6554 -  info - structure containing
6555 $      levels - number of levels of fill.
6556 $      expected fill - as ratio of original fill.
6557 
6558    Output Parameter:
6559 .  fact - the factored matrix
6560 
6561    Notes:
6562    Most users should employ the KSP interface for linear solvers
6563    instead of working directly with matrix algebra routines such as this.
6564    See, e.g., KSPCreate().
6565 
6566    Level: developer
6567 
6568 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6569 
6570     Note: this uses the definition of level of fill as in Y. Saad, 2003
6571 
6572     Developer Note: fortran interface is not autogenerated as the f90
6573     interface defintion cannot be generated correctly [due to MatFactorInfo]
6574 
6575    References:
6576      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6577 @*/
6578 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6579 {
6580   PetscErrorCode ierr;
6581 
6582   PetscFunctionBegin;
6583   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6584   PetscValidType(mat,1);
6585   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6586   PetscValidPointer(info,3);
6587   PetscValidPointer(fact,4);
6588   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6589   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6590   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6591   if (!(fact)->ops->iccfactorsymbolic) {
6592     MatSolverType spackage;
6593     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6594     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6595   }
6596   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6597   MatCheckPreallocated(mat,2);
6598 
6599   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6600   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6601   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6602   PetscFunctionReturn(0);
6603 }
6604 
6605 /*@C
6606    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6607    points to an array of valid matrices, they may be reused to store the new
6608    submatrices.
6609 
6610    Collective on Mat
6611 
6612    Input Parameters:
6613 +  mat - the matrix
6614 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6615 .  irow, icol - index sets of rows and columns to extract
6616 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6617 
6618    Output Parameter:
6619 .  submat - the array of submatrices
6620 
6621    Notes:
6622    MatCreateSubMatrices() can extract ONLY sequential submatrices
6623    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6624    to extract a parallel submatrix.
6625 
6626    Some matrix types place restrictions on the row and column
6627    indices, such as that they be sorted or that they be equal to each other.
6628 
6629    The index sets may not have duplicate entries.
6630 
6631    When extracting submatrices from a parallel matrix, each processor can
6632    form a different submatrix by setting the rows and columns of its
6633    individual index sets according to the local submatrix desired.
6634 
6635    When finished using the submatrices, the user should destroy
6636    them with MatDestroySubMatrices().
6637 
6638    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6639    original matrix has not changed from that last call to MatCreateSubMatrices().
6640 
6641    This routine creates the matrices in submat; you should NOT create them before
6642    calling it. It also allocates the array of matrix pointers submat.
6643 
6644    For BAIJ matrices the index sets must respect the block structure, that is if they
6645    request one row/column in a block, they must request all rows/columns that are in
6646    that block. For example, if the block size is 2 you cannot request just row 0 and
6647    column 0.
6648 
6649    Fortran Note:
6650    The Fortran interface is slightly different from that given below; it
6651    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6652 
6653    Level: advanced
6654 
6655 
6656 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6657 @*/
6658 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6659 {
6660   PetscErrorCode ierr;
6661   PetscInt       i;
6662   PetscBool      eq;
6663 
6664   PetscFunctionBegin;
6665   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6666   PetscValidType(mat,1);
6667   if (n) {
6668     PetscValidPointer(irow,3);
6669     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6670     PetscValidPointer(icol,4);
6671     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6672   }
6673   PetscValidPointer(submat,6);
6674   if (n && scall == MAT_REUSE_MATRIX) {
6675     PetscValidPointer(*submat,6);
6676     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6677   }
6678   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6679   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6680   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6681   MatCheckPreallocated(mat,1);
6682 
6683   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6684   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6685   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6686   for (i=0; i<n; i++) {
6687     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6688     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6689       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6690       if (eq) {
6691         if (mat->symmetric) {
6692           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6693         } else if (mat->hermitian) {
6694           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6695         } else if (mat->structurally_symmetric) {
6696           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6697         }
6698       }
6699     }
6700   }
6701   PetscFunctionReturn(0);
6702 }
6703 
6704 /*@C
6705    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6706 
6707    Collective on Mat
6708 
6709    Input Parameters:
6710 +  mat - the matrix
6711 .  n   - the number of submatrixes to be extracted
6712 .  irow, icol - index sets of rows and columns to extract
6713 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6714 
6715    Output Parameter:
6716 .  submat - the array of submatrices
6717 
6718    Level: advanced
6719 
6720 
6721 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6722 @*/
6723 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6724 {
6725   PetscErrorCode ierr;
6726   PetscInt       i;
6727   PetscBool      eq;
6728 
6729   PetscFunctionBegin;
6730   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6731   PetscValidType(mat,1);
6732   if (n) {
6733     PetscValidPointer(irow,3);
6734     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6735     PetscValidPointer(icol,4);
6736     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6737   }
6738   PetscValidPointer(submat,6);
6739   if (n && scall == MAT_REUSE_MATRIX) {
6740     PetscValidPointer(*submat,6);
6741     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6742   }
6743   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6744   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6745   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6746   MatCheckPreallocated(mat,1);
6747 
6748   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6749   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6750   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6751   for (i=0; i<n; i++) {
6752     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6753       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6754       if (eq) {
6755         if (mat->symmetric) {
6756           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6757         } else if (mat->hermitian) {
6758           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6759         } else if (mat->structurally_symmetric) {
6760           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6761         }
6762       }
6763     }
6764   }
6765   PetscFunctionReturn(0);
6766 }
6767 
6768 /*@C
6769    MatDestroyMatrices - Destroys an array of matrices.
6770 
6771    Collective on Mat
6772 
6773    Input Parameters:
6774 +  n - the number of local matrices
6775 -  mat - the matrices (note that this is a pointer to the array of matrices)
6776 
6777    Level: advanced
6778 
6779     Notes:
6780     Frees not only the matrices, but also the array that contains the matrices
6781            In Fortran will not free the array.
6782 
6783 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6784 @*/
6785 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6786 {
6787   PetscErrorCode ierr;
6788   PetscInt       i;
6789 
6790   PetscFunctionBegin;
6791   if (!*mat) PetscFunctionReturn(0);
6792   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6793   PetscValidPointer(mat,2);
6794 
6795   for (i=0; i<n; i++) {
6796     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6797   }
6798 
6799   /* memory is allocated even if n = 0 */
6800   ierr = PetscFree(*mat);CHKERRQ(ierr);
6801   PetscFunctionReturn(0);
6802 }
6803 
6804 /*@C
6805    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6806 
6807    Collective on Mat
6808 
6809    Input Parameters:
6810 +  n - the number of local matrices
6811 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6812                        sequence of MatCreateSubMatrices())
6813 
6814    Level: advanced
6815 
6816     Notes:
6817     Frees not only the matrices, but also the array that contains the matrices
6818            In Fortran will not free the array.
6819 
6820 .seealso: MatCreateSubMatrices()
6821 @*/
6822 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6823 {
6824   PetscErrorCode ierr;
6825   Mat            mat0;
6826 
6827   PetscFunctionBegin;
6828   if (!*mat) PetscFunctionReturn(0);
6829   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6830   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6831   PetscValidPointer(mat,2);
6832 
6833   mat0 = (*mat)[0];
6834   if (mat0 && mat0->ops->destroysubmatrices) {
6835     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6836   } else {
6837     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6838   }
6839   PetscFunctionReturn(0);
6840 }
6841 
6842 /*@C
6843    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6844 
6845    Collective on Mat
6846 
6847    Input Parameters:
6848 .  mat - the matrix
6849 
6850    Output Parameter:
6851 .  matstruct - the sequential matrix with the nonzero structure of mat
6852 
6853   Level: intermediate
6854 
6855 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6856 @*/
6857 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6858 {
6859   PetscErrorCode ierr;
6860 
6861   PetscFunctionBegin;
6862   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6863   PetscValidPointer(matstruct,2);
6864 
6865   PetscValidType(mat,1);
6866   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6867   MatCheckPreallocated(mat,1);
6868 
6869   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6870   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6871   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6872   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6873   PetscFunctionReturn(0);
6874 }
6875 
6876 /*@C
6877    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6878 
6879    Collective on Mat
6880 
6881    Input Parameters:
6882 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6883                        sequence of MatGetSequentialNonzeroStructure())
6884 
6885    Level: advanced
6886 
6887     Notes:
6888     Frees not only the matrices, but also the array that contains the matrices
6889 
6890 .seealso: MatGetSeqNonzeroStructure()
6891 @*/
6892 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6893 {
6894   PetscErrorCode ierr;
6895 
6896   PetscFunctionBegin;
6897   PetscValidPointer(mat,1);
6898   ierr = MatDestroy(mat);CHKERRQ(ierr);
6899   PetscFunctionReturn(0);
6900 }
6901 
6902 /*@
6903    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6904    replaces the index sets by larger ones that represent submatrices with
6905    additional overlap.
6906 
6907    Collective on Mat
6908 
6909    Input Parameters:
6910 +  mat - the matrix
6911 .  n   - the number of index sets
6912 .  is  - the array of index sets (these index sets will changed during the call)
6913 -  ov  - the additional overlap requested
6914 
6915    Options Database:
6916 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6917 
6918    Level: developer
6919 
6920 
6921 .seealso: MatCreateSubMatrices()
6922 @*/
6923 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6924 {
6925   PetscErrorCode ierr;
6926 
6927   PetscFunctionBegin;
6928   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6929   PetscValidType(mat,1);
6930   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6931   if (n) {
6932     PetscValidPointer(is,3);
6933     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6934   }
6935   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6936   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6937   MatCheckPreallocated(mat,1);
6938 
6939   if (!ov) PetscFunctionReturn(0);
6940   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6941   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6942   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6943   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6944   PetscFunctionReturn(0);
6945 }
6946 
6947 
6948 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6949 
6950 /*@
6951    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6952    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6953    additional overlap.
6954 
6955    Collective on Mat
6956 
6957    Input Parameters:
6958 +  mat - the matrix
6959 .  n   - the number of index sets
6960 .  is  - the array of index sets (these index sets will changed during the call)
6961 -  ov  - the additional overlap requested
6962 
6963    Options Database:
6964 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6965 
6966    Level: developer
6967 
6968 
6969 .seealso: MatCreateSubMatrices()
6970 @*/
6971 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6972 {
6973   PetscInt       i;
6974   PetscErrorCode ierr;
6975 
6976   PetscFunctionBegin;
6977   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6978   PetscValidType(mat,1);
6979   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6980   if (n) {
6981     PetscValidPointer(is,3);
6982     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6983   }
6984   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6985   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6986   MatCheckPreallocated(mat,1);
6987   if (!ov) PetscFunctionReturn(0);
6988   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6989   for(i=0; i<n; i++){
6990 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
6991   }
6992   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6993   PetscFunctionReturn(0);
6994 }
6995 
6996 
6997 
6998 
6999 /*@
7000    MatGetBlockSize - Returns the matrix block size.
7001 
7002    Not Collective
7003 
7004    Input Parameter:
7005 .  mat - the matrix
7006 
7007    Output Parameter:
7008 .  bs - block size
7009 
7010    Notes:
7011     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7012 
7013    If the block size has not been set yet this routine returns 1.
7014 
7015    Level: intermediate
7016 
7017 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7018 @*/
7019 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7020 {
7021   PetscFunctionBegin;
7022   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7023   PetscValidIntPointer(bs,2);
7024   *bs = PetscAbs(mat->rmap->bs);
7025   PetscFunctionReturn(0);
7026 }
7027 
7028 /*@
7029    MatGetBlockSizes - Returns the matrix block row and column sizes.
7030 
7031    Not Collective
7032 
7033    Input Parameter:
7034 .  mat - the matrix
7035 
7036    Output Parameter:
7037 +  rbs - row block size
7038 -  cbs - column block size
7039 
7040    Notes:
7041     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7042     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7043 
7044    If a block size has not been set yet this routine returns 1.
7045 
7046    Level: intermediate
7047 
7048 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7049 @*/
7050 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7051 {
7052   PetscFunctionBegin;
7053   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7054   if (rbs) PetscValidIntPointer(rbs,2);
7055   if (cbs) PetscValidIntPointer(cbs,3);
7056   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7057   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7058   PetscFunctionReturn(0);
7059 }
7060 
7061 /*@
7062    MatSetBlockSize - Sets the matrix block size.
7063 
7064    Logically Collective on Mat
7065 
7066    Input Parameters:
7067 +  mat - the matrix
7068 -  bs - block size
7069 
7070    Notes:
7071     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7072     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7073 
7074     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7075     is compatible with the matrix local sizes.
7076 
7077    Level: intermediate
7078 
7079 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7080 @*/
7081 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7082 {
7083   PetscErrorCode ierr;
7084 
7085   PetscFunctionBegin;
7086   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7087   PetscValidLogicalCollectiveInt(mat,bs,2);
7088   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7089   PetscFunctionReturn(0);
7090 }
7091 
7092 /*@
7093    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7094 
7095    Logically Collective on Mat
7096 
7097    Input Parameters:
7098 +  mat - the matrix
7099 .  nblocks - the number of blocks on this process
7100 -  bsizes - the block sizes
7101 
7102    Notes:
7103     Currently used by PCVPBJACOBI for SeqAIJ matrices
7104 
7105    Level: intermediate
7106 
7107 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7108 @*/
7109 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7110 {
7111   PetscErrorCode ierr;
7112   PetscInt       i,ncnt = 0, nlocal;
7113 
7114   PetscFunctionBegin;
7115   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7116   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7117   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7118   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7119   if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7120   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7121   mat->nblocks = nblocks;
7122   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7123   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7124   PetscFunctionReturn(0);
7125 }
7126 
7127 /*@C
7128    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7129 
7130    Logically Collective on Mat
7131 
7132    Input Parameters:
7133 .  mat - the matrix
7134 
7135    Output Parameters:
7136 +  nblocks - the number of blocks on this process
7137 -  bsizes - the block sizes
7138 
7139    Notes: Currently not supported from Fortran
7140 
7141    Level: intermediate
7142 
7143 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7144 @*/
7145 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7146 {
7147   PetscFunctionBegin;
7148   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7149   *nblocks = mat->nblocks;
7150   *bsizes  = mat->bsizes;
7151   PetscFunctionReturn(0);
7152 }
7153 
7154 /*@
7155    MatSetBlockSizes - Sets the matrix block row and column sizes.
7156 
7157    Logically Collective on Mat
7158 
7159    Input Parameters:
7160 +  mat - the matrix
7161 -  rbs - row block size
7162 -  cbs - column block size
7163 
7164    Notes:
7165     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7166     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7167     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7168 
7169     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7170     are compatible with the matrix local sizes.
7171 
7172     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7173 
7174    Level: intermediate
7175 
7176 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7177 @*/
7178 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7179 {
7180   PetscErrorCode ierr;
7181 
7182   PetscFunctionBegin;
7183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7184   PetscValidLogicalCollectiveInt(mat,rbs,2);
7185   PetscValidLogicalCollectiveInt(mat,cbs,3);
7186   if (mat->ops->setblocksizes) {
7187     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7188   }
7189   if (mat->rmap->refcnt) {
7190     ISLocalToGlobalMapping l2g = NULL;
7191     PetscLayout            nmap = NULL;
7192 
7193     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7194     if (mat->rmap->mapping) {
7195       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7196     }
7197     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7198     mat->rmap = nmap;
7199     mat->rmap->mapping = l2g;
7200   }
7201   if (mat->cmap->refcnt) {
7202     ISLocalToGlobalMapping l2g = NULL;
7203     PetscLayout            nmap = NULL;
7204 
7205     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7206     if (mat->cmap->mapping) {
7207       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7208     }
7209     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7210     mat->cmap = nmap;
7211     mat->cmap->mapping = l2g;
7212   }
7213   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7214   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7215   PetscFunctionReturn(0);
7216 }
7217 
7218 /*@
7219    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7220 
7221    Logically Collective on Mat
7222 
7223    Input Parameters:
7224 +  mat - the matrix
7225 .  fromRow - matrix from which to copy row block size
7226 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7227 
7228    Level: developer
7229 
7230 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7231 @*/
7232 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7233 {
7234   PetscErrorCode ierr;
7235 
7236   PetscFunctionBegin;
7237   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7238   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7239   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7240   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7241   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7242   PetscFunctionReturn(0);
7243 }
7244 
7245 /*@
7246    MatResidual - Default routine to calculate the residual.
7247 
7248    Collective on Mat
7249 
7250    Input Parameters:
7251 +  mat - the matrix
7252 .  b   - the right-hand-side
7253 -  x   - the approximate solution
7254 
7255    Output Parameter:
7256 .  r - location to store the residual
7257 
7258    Level: developer
7259 
7260 .seealso: PCMGSetResidual()
7261 @*/
7262 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7263 {
7264   PetscErrorCode ierr;
7265 
7266   PetscFunctionBegin;
7267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7268   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7269   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7270   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7271   PetscValidType(mat,1);
7272   MatCheckPreallocated(mat,1);
7273   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7274   if (!mat->ops->residual) {
7275     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7276     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7277   } else {
7278     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7279   }
7280   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7281   PetscFunctionReturn(0);
7282 }
7283 
7284 /*@C
7285     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7286 
7287    Collective on Mat
7288 
7289     Input Parameters:
7290 +   mat - the matrix
7291 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7292 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7293 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7294                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7295                  always used.
7296 
7297     Output Parameters:
7298 +   n - number of rows in the (possibly compressed) matrix
7299 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7300 .   ja - the column indices
7301 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7302            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7303 
7304     Level: developer
7305 
7306     Notes:
7307     You CANNOT change any of the ia[] or ja[] values.
7308 
7309     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7310 
7311     Fortran Notes:
7312     In Fortran use
7313 $
7314 $      PetscInt ia(1), ja(1)
7315 $      PetscOffset iia, jja
7316 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7317 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7318 
7319      or
7320 $
7321 $    PetscInt, pointer :: ia(:),ja(:)
7322 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7323 $    ! Access the ith and jth entries via ia(i) and ja(j)
7324 
7325 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7326 @*/
7327 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7328 {
7329   PetscErrorCode ierr;
7330 
7331   PetscFunctionBegin;
7332   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7333   PetscValidType(mat,1);
7334   PetscValidIntPointer(n,5);
7335   if (ia) PetscValidIntPointer(ia,6);
7336   if (ja) PetscValidIntPointer(ja,7);
7337   PetscValidIntPointer(done,8);
7338   MatCheckPreallocated(mat,1);
7339   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7340   else {
7341     *done = PETSC_TRUE;
7342     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7343     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7344     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7345   }
7346   PetscFunctionReturn(0);
7347 }
7348 
7349 /*@C
7350     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7351 
7352     Collective on Mat
7353 
7354     Input Parameters:
7355 +   mat - the matrix
7356 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7357 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7358                 symmetrized
7359 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7360                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7361                  always used.
7362 .   n - number of columns in the (possibly compressed) matrix
7363 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7364 -   ja - the row indices
7365 
7366     Output Parameters:
7367 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7368 
7369     Level: developer
7370 
7371 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7372 @*/
7373 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7374 {
7375   PetscErrorCode ierr;
7376 
7377   PetscFunctionBegin;
7378   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7379   PetscValidType(mat,1);
7380   PetscValidIntPointer(n,4);
7381   if (ia) PetscValidIntPointer(ia,5);
7382   if (ja) PetscValidIntPointer(ja,6);
7383   PetscValidIntPointer(done,7);
7384   MatCheckPreallocated(mat,1);
7385   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7386   else {
7387     *done = PETSC_TRUE;
7388     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7389   }
7390   PetscFunctionReturn(0);
7391 }
7392 
7393 /*@C
7394     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7395     MatGetRowIJ().
7396 
7397     Collective on Mat
7398 
7399     Input Parameters:
7400 +   mat - the matrix
7401 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7402 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7403                 symmetrized
7404 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7405                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7406                  always used.
7407 .   n - size of (possibly compressed) matrix
7408 .   ia - the row pointers
7409 -   ja - the column indices
7410 
7411     Output Parameters:
7412 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7413 
7414     Note:
7415     This routine zeros out n, ia, and ja. This is to prevent accidental
7416     us of the array after it has been restored. If you pass NULL, it will
7417     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7418 
7419     Level: developer
7420 
7421 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7422 @*/
7423 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7424 {
7425   PetscErrorCode ierr;
7426 
7427   PetscFunctionBegin;
7428   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7429   PetscValidType(mat,1);
7430   if (ia) PetscValidIntPointer(ia,6);
7431   if (ja) PetscValidIntPointer(ja,7);
7432   PetscValidIntPointer(done,8);
7433   MatCheckPreallocated(mat,1);
7434 
7435   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7436   else {
7437     *done = PETSC_TRUE;
7438     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7439     if (n)  *n = 0;
7440     if (ia) *ia = NULL;
7441     if (ja) *ja = NULL;
7442   }
7443   PetscFunctionReturn(0);
7444 }
7445 
7446 /*@C
7447     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7448     MatGetColumnIJ().
7449 
7450     Collective on Mat
7451 
7452     Input Parameters:
7453 +   mat - the matrix
7454 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7455 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7456                 symmetrized
7457 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7458                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7459                  always used.
7460 
7461     Output Parameters:
7462 +   n - size of (possibly compressed) matrix
7463 .   ia - the column pointers
7464 .   ja - the row indices
7465 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7466 
7467     Level: developer
7468 
7469 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7470 @*/
7471 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7472 {
7473   PetscErrorCode ierr;
7474 
7475   PetscFunctionBegin;
7476   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7477   PetscValidType(mat,1);
7478   if (ia) PetscValidIntPointer(ia,5);
7479   if (ja) PetscValidIntPointer(ja,6);
7480   PetscValidIntPointer(done,7);
7481   MatCheckPreallocated(mat,1);
7482 
7483   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7484   else {
7485     *done = PETSC_TRUE;
7486     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7487     if (n)  *n = 0;
7488     if (ia) *ia = NULL;
7489     if (ja) *ja = NULL;
7490   }
7491   PetscFunctionReturn(0);
7492 }
7493 
7494 /*@C
7495     MatColoringPatch -Used inside matrix coloring routines that
7496     use MatGetRowIJ() and/or MatGetColumnIJ().
7497 
7498     Collective on Mat
7499 
7500     Input Parameters:
7501 +   mat - the matrix
7502 .   ncolors - max color value
7503 .   n   - number of entries in colorarray
7504 -   colorarray - array indicating color for each column
7505 
7506     Output Parameters:
7507 .   iscoloring - coloring generated using colorarray information
7508 
7509     Level: developer
7510 
7511 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7512 
7513 @*/
7514 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7515 {
7516   PetscErrorCode ierr;
7517 
7518   PetscFunctionBegin;
7519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7520   PetscValidType(mat,1);
7521   PetscValidIntPointer(colorarray,4);
7522   PetscValidPointer(iscoloring,5);
7523   MatCheckPreallocated(mat,1);
7524 
7525   if (!mat->ops->coloringpatch) {
7526     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7527   } else {
7528     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7529   }
7530   PetscFunctionReturn(0);
7531 }
7532 
7533 
7534 /*@
7535    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7536 
7537    Logically Collective on Mat
7538 
7539    Input Parameter:
7540 .  mat - the factored matrix to be reset
7541 
7542    Notes:
7543    This routine should be used only with factored matrices formed by in-place
7544    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7545    format).  This option can save memory, for example, when solving nonlinear
7546    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7547    ILU(0) preconditioner.
7548 
7549    Note that one can specify in-place ILU(0) factorization by calling
7550 .vb
7551      PCType(pc,PCILU);
7552      PCFactorSeUseInPlace(pc);
7553 .ve
7554    or by using the options -pc_type ilu -pc_factor_in_place
7555 
7556    In-place factorization ILU(0) can also be used as a local
7557    solver for the blocks within the block Jacobi or additive Schwarz
7558    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7559    for details on setting local solver options.
7560 
7561    Most users should employ the simplified KSP interface for linear solvers
7562    instead of working directly with matrix algebra routines such as this.
7563    See, e.g., KSPCreate().
7564 
7565    Level: developer
7566 
7567 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7568 
7569 @*/
7570 PetscErrorCode MatSetUnfactored(Mat mat)
7571 {
7572   PetscErrorCode ierr;
7573 
7574   PetscFunctionBegin;
7575   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7576   PetscValidType(mat,1);
7577   MatCheckPreallocated(mat,1);
7578   mat->factortype = MAT_FACTOR_NONE;
7579   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7580   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7581   PetscFunctionReturn(0);
7582 }
7583 
7584 /*MC
7585     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7586 
7587     Synopsis:
7588     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7589 
7590     Not collective
7591 
7592     Input Parameter:
7593 .   x - matrix
7594 
7595     Output Parameters:
7596 +   xx_v - the Fortran90 pointer to the array
7597 -   ierr - error code
7598 
7599     Example of Usage:
7600 .vb
7601       PetscScalar, pointer xx_v(:,:)
7602       ....
7603       call MatDenseGetArrayF90(x,xx_v,ierr)
7604       a = xx_v(3)
7605       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7606 .ve
7607 
7608     Level: advanced
7609 
7610 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7611 
7612 M*/
7613 
7614 /*MC
7615     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7616     accessed with MatDenseGetArrayF90().
7617 
7618     Synopsis:
7619     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7620 
7621     Not collective
7622 
7623     Input Parameters:
7624 +   x - matrix
7625 -   xx_v - the Fortran90 pointer to the array
7626 
7627     Output Parameter:
7628 .   ierr - error code
7629 
7630     Example of Usage:
7631 .vb
7632        PetscScalar, pointer xx_v(:,:)
7633        ....
7634        call MatDenseGetArrayF90(x,xx_v,ierr)
7635        a = xx_v(3)
7636        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7637 .ve
7638 
7639     Level: advanced
7640 
7641 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7642 
7643 M*/
7644 
7645 
7646 /*MC
7647     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7648 
7649     Synopsis:
7650     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7651 
7652     Not collective
7653 
7654     Input Parameter:
7655 .   x - matrix
7656 
7657     Output Parameters:
7658 +   xx_v - the Fortran90 pointer to the array
7659 -   ierr - error code
7660 
7661     Example of Usage:
7662 .vb
7663       PetscScalar, pointer xx_v(:)
7664       ....
7665       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7666       a = xx_v(3)
7667       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7668 .ve
7669 
7670     Level: advanced
7671 
7672 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7673 
7674 M*/
7675 
7676 /*MC
7677     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7678     accessed with MatSeqAIJGetArrayF90().
7679 
7680     Synopsis:
7681     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7682 
7683     Not collective
7684 
7685     Input Parameters:
7686 +   x - matrix
7687 -   xx_v - the Fortran90 pointer to the array
7688 
7689     Output Parameter:
7690 .   ierr - error code
7691 
7692     Example of Usage:
7693 .vb
7694        PetscScalar, pointer xx_v(:)
7695        ....
7696        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7697        a = xx_v(3)
7698        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7699 .ve
7700 
7701     Level: advanced
7702 
7703 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7704 
7705 M*/
7706 
7707 
7708 /*@
7709     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7710                       as the original matrix.
7711 
7712     Collective on Mat
7713 
7714     Input Parameters:
7715 +   mat - the original matrix
7716 .   isrow - parallel IS containing the rows this processor should obtain
7717 .   iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7718 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7719 
7720     Output Parameter:
7721 .   newmat - the new submatrix, of the same type as the old
7722 
7723     Level: advanced
7724 
7725     Notes:
7726     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7727 
7728     Some matrix types place restrictions on the row and column indices, such
7729     as that they be sorted or that they be equal to each other.
7730 
7731     The index sets may not have duplicate entries.
7732 
7733       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7734    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7735    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7736    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7737    you are finished using it.
7738 
7739     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7740     the input matrix.
7741 
7742     If iscol is NULL then all columns are obtained (not supported in Fortran).
7743 
7744    Example usage:
7745    Consider the following 8x8 matrix with 34 non-zero values, that is
7746    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7747    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7748    as follows:
7749 
7750 .vb
7751             1  2  0  |  0  3  0  |  0  4
7752     Proc0   0  5  6  |  7  0  0  |  8  0
7753             9  0 10  | 11  0  0  | 12  0
7754     -------------------------------------
7755            13  0 14  | 15 16 17  |  0  0
7756     Proc1   0 18  0  | 19 20 21  |  0  0
7757             0  0  0  | 22 23  0  | 24  0
7758     -------------------------------------
7759     Proc2  25 26 27  |  0  0 28  | 29  0
7760            30  0  0  | 31 32 33  |  0 34
7761 .ve
7762 
7763     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7764 
7765 .vb
7766             2  0  |  0  3  0  |  0
7767     Proc0   5  6  |  7  0  0  |  8
7768     -------------------------------
7769     Proc1  18  0  | 19 20 21  |  0
7770     -------------------------------
7771     Proc2  26 27  |  0  0 28  | 29
7772             0  0  | 31 32 33  |  0
7773 .ve
7774 
7775 
7776 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
7777 @*/
7778 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7779 {
7780   PetscErrorCode ierr;
7781   PetscMPIInt    size;
7782   Mat            *local;
7783   IS             iscoltmp;
7784 
7785   PetscFunctionBegin;
7786   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7787   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7788   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7789   PetscValidPointer(newmat,5);
7790   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7791   PetscValidType(mat,1);
7792   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7793   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7794 
7795   MatCheckPreallocated(mat,1);
7796   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7797 
7798   if (!iscol || isrow == iscol) {
7799     PetscBool   stride;
7800     PetscMPIInt grabentirematrix = 0,grab;
7801     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7802     if (stride) {
7803       PetscInt first,step,n,rstart,rend;
7804       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7805       if (step == 1) {
7806         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7807         if (rstart == first) {
7808           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7809           if (n == rend-rstart) {
7810             grabentirematrix = 1;
7811           }
7812         }
7813       }
7814     }
7815     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7816     if (grab) {
7817       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7818       if (cll == MAT_INITIAL_MATRIX) {
7819         *newmat = mat;
7820         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7821       }
7822       PetscFunctionReturn(0);
7823     }
7824   }
7825 
7826   if (!iscol) {
7827     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7828   } else {
7829     iscoltmp = iscol;
7830   }
7831 
7832   /* if original matrix is on just one processor then use submatrix generated */
7833   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7834     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7835     goto setproperties;
7836   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7837     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7838     *newmat = *local;
7839     ierr    = PetscFree(local);CHKERRQ(ierr);
7840     goto setproperties;
7841   } else if (!mat->ops->createsubmatrix) {
7842     /* Create a new matrix type that implements the operation using the full matrix */
7843     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7844     switch (cll) {
7845     case MAT_INITIAL_MATRIX:
7846       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7847       break;
7848     case MAT_REUSE_MATRIX:
7849       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7850       break;
7851     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7852     }
7853     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7854     goto setproperties;
7855   }
7856 
7857   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7858   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7859   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7860   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7861 
7862   /* Propagate symmetry information for diagonal blocks */
7863 setproperties:
7864   if (isrow == iscoltmp) {
7865     if (mat->symmetric_set && mat->symmetric) {
7866       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7867     }
7868     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
7869       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7870     }
7871     if (mat->hermitian_set && mat->hermitian) {
7872       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7873     }
7874     if (mat->spd_set && mat->spd) {
7875       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
7876     }
7877   }
7878 
7879   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7880   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7881   PetscFunctionReturn(0);
7882 }
7883 
7884 /*@
7885    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7886    used during the assembly process to store values that belong to
7887    other processors.
7888 
7889    Not Collective
7890 
7891    Input Parameters:
7892 +  mat   - the matrix
7893 .  size  - the initial size of the stash.
7894 -  bsize - the initial size of the block-stash(if used).
7895 
7896    Options Database Keys:
7897 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7898 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7899 
7900    Level: intermediate
7901 
7902    Notes:
7903      The block-stash is used for values set with MatSetValuesBlocked() while
7904      the stash is used for values set with MatSetValues()
7905 
7906      Run with the option -info and look for output of the form
7907      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7908      to determine the appropriate value, MM, to use for size and
7909      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7910      to determine the value, BMM to use for bsize
7911 
7912 
7913 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7914 
7915 @*/
7916 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7917 {
7918   PetscErrorCode ierr;
7919 
7920   PetscFunctionBegin;
7921   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7922   PetscValidType(mat,1);
7923   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7924   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7925   PetscFunctionReturn(0);
7926 }
7927 
7928 /*@
7929    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7930      the matrix
7931 
7932    Neighbor-wise Collective on Mat
7933 
7934    Input Parameters:
7935 +  mat   - the matrix
7936 .  x,y - the vectors
7937 -  w - where the result is stored
7938 
7939    Level: intermediate
7940 
7941    Notes:
7942     w may be the same vector as y.
7943 
7944     This allows one to use either the restriction or interpolation (its transpose)
7945     matrix to do the interpolation
7946 
7947 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7948 
7949 @*/
7950 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7951 {
7952   PetscErrorCode ierr;
7953   PetscInt       M,N,Ny;
7954 
7955   PetscFunctionBegin;
7956   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7957   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7958   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7959   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7960   PetscValidType(A,1);
7961   MatCheckPreallocated(A,1);
7962   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7963   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7964   if (M == Ny) {
7965     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7966   } else {
7967     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7968   }
7969   PetscFunctionReturn(0);
7970 }
7971 
7972 /*@
7973    MatInterpolate - y = A*x or A'*x depending on the shape of
7974      the matrix
7975 
7976    Neighbor-wise Collective on Mat
7977 
7978    Input Parameters:
7979 +  mat   - the matrix
7980 -  x,y - the vectors
7981 
7982    Level: intermediate
7983 
7984    Notes:
7985     This allows one to use either the restriction or interpolation (its transpose)
7986     matrix to do the interpolation
7987 
7988 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7989 
7990 @*/
7991 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7992 {
7993   PetscErrorCode ierr;
7994   PetscInt       M,N,Ny;
7995 
7996   PetscFunctionBegin;
7997   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7998   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7999   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8000   PetscValidType(A,1);
8001   MatCheckPreallocated(A,1);
8002   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8003   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8004   if (M == Ny) {
8005     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8006   } else {
8007     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8008   }
8009   PetscFunctionReturn(0);
8010 }
8011 
8012 /*@
8013    MatRestrict - y = A*x or A'*x
8014 
8015    Neighbor-wise Collective on Mat
8016 
8017    Input Parameters:
8018 +  mat   - the matrix
8019 -  x,y - the vectors
8020 
8021    Level: intermediate
8022 
8023    Notes:
8024     This allows one to use either the restriction or interpolation (its transpose)
8025     matrix to do the restriction
8026 
8027 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8028 
8029 @*/
8030 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8031 {
8032   PetscErrorCode ierr;
8033   PetscInt       M,N,Ny;
8034 
8035   PetscFunctionBegin;
8036   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8037   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8038   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8039   PetscValidType(A,1);
8040   MatCheckPreallocated(A,1);
8041 
8042   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8043   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8044   if (M == Ny) {
8045     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8046   } else {
8047     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8048   }
8049   PetscFunctionReturn(0);
8050 }
8051 
8052 /*@
8053    MatGetNullSpace - retrieves the null space of a matrix.
8054 
8055    Logically Collective on Mat
8056 
8057    Input Parameters:
8058 +  mat - the matrix
8059 -  nullsp - the null space object
8060 
8061    Level: developer
8062 
8063 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8064 @*/
8065 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8066 {
8067   PetscFunctionBegin;
8068   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8069   PetscValidPointer(nullsp,2);
8070   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8071   PetscFunctionReturn(0);
8072 }
8073 
8074 /*@
8075    MatSetNullSpace - attaches a null space to a matrix.
8076 
8077    Logically Collective on Mat
8078 
8079    Input Parameters:
8080 +  mat - the matrix
8081 -  nullsp - the null space object
8082 
8083    Level: advanced
8084 
8085    Notes:
8086       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8087 
8088       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8089       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8090 
8091       You can remove the null space by calling this routine with an nullsp of NULL
8092 
8093 
8094       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8095    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).
8096    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
8097    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
8098    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).
8099 
8100       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8101 
8102     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
8103     routine also automatically calls MatSetTransposeNullSpace().
8104 
8105 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8106 @*/
8107 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8108 {
8109   PetscErrorCode ierr;
8110 
8111   PetscFunctionBegin;
8112   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8113   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8114   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8115   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8116   mat->nullsp = nullsp;
8117   if (mat->symmetric_set && mat->symmetric) {
8118     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8119   }
8120   PetscFunctionReturn(0);
8121 }
8122 
8123 /*@
8124    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8125 
8126    Logically Collective on Mat
8127 
8128    Input Parameters:
8129 +  mat - the matrix
8130 -  nullsp - the null space object
8131 
8132    Level: developer
8133 
8134 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8135 @*/
8136 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8137 {
8138   PetscFunctionBegin;
8139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8140   PetscValidType(mat,1);
8141   PetscValidPointer(nullsp,2);
8142   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8143   PetscFunctionReturn(0);
8144 }
8145 
8146 /*@
8147    MatSetTransposeNullSpace - attaches a null space to a matrix.
8148 
8149    Logically Collective on Mat
8150 
8151    Input Parameters:
8152 +  mat - the matrix
8153 -  nullsp - the null space object
8154 
8155    Level: advanced
8156 
8157    Notes:
8158       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.
8159       You must also call MatSetNullSpace()
8160 
8161 
8162       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8163    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).
8164    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
8165    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
8166    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).
8167 
8168       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8169 
8170 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8171 @*/
8172 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8173 {
8174   PetscErrorCode ierr;
8175 
8176   PetscFunctionBegin;
8177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8178   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8179   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8180   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8181   mat->transnullsp = nullsp;
8182   PetscFunctionReturn(0);
8183 }
8184 
8185 /*@
8186    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8187         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8188 
8189    Logically Collective on Mat
8190 
8191    Input Parameters:
8192 +  mat - the matrix
8193 -  nullsp - the null space object
8194 
8195    Level: advanced
8196 
8197    Notes:
8198       Overwrites any previous near null space that may have been attached
8199 
8200       You can remove the null space by calling this routine with an nullsp of NULL
8201 
8202 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8203 @*/
8204 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8205 {
8206   PetscErrorCode ierr;
8207 
8208   PetscFunctionBegin;
8209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8210   PetscValidType(mat,1);
8211   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8212   MatCheckPreallocated(mat,1);
8213   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8214   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8215   mat->nearnullsp = nullsp;
8216   PetscFunctionReturn(0);
8217 }
8218 
8219 /*@
8220    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8221 
8222    Not Collective
8223 
8224    Input Parameter:
8225 .  mat - the matrix
8226 
8227    Output Parameter:
8228 .  nullsp - the null space object, NULL if not set
8229 
8230    Level: developer
8231 
8232 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8233 @*/
8234 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8235 {
8236   PetscFunctionBegin;
8237   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8238   PetscValidType(mat,1);
8239   PetscValidPointer(nullsp,2);
8240   MatCheckPreallocated(mat,1);
8241   *nullsp = mat->nearnullsp;
8242   PetscFunctionReturn(0);
8243 }
8244 
8245 /*@C
8246    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8247 
8248    Collective on Mat
8249 
8250    Input Parameters:
8251 +  mat - the matrix
8252 .  row - row/column permutation
8253 .  fill - expected fill factor >= 1.0
8254 -  level - level of fill, for ICC(k)
8255 
8256    Notes:
8257    Probably really in-place only when level of fill is zero, otherwise allocates
8258    new space to store factored matrix and deletes previous memory.
8259 
8260    Most users should employ the simplified KSP interface for linear solvers
8261    instead of working directly with matrix algebra routines such as this.
8262    See, e.g., KSPCreate().
8263 
8264    Level: developer
8265 
8266 
8267 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8268 
8269     Developer Note: fortran interface is not autogenerated as the f90
8270     interface defintion cannot be generated correctly [due to MatFactorInfo]
8271 
8272 @*/
8273 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8274 {
8275   PetscErrorCode ierr;
8276 
8277   PetscFunctionBegin;
8278   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8279   PetscValidType(mat,1);
8280   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8281   PetscValidPointer(info,3);
8282   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8283   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8284   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8285   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8286   MatCheckPreallocated(mat,1);
8287   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8288   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8289   PetscFunctionReturn(0);
8290 }
8291 
8292 /*@
8293    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8294          ghosted ones.
8295 
8296    Not Collective
8297 
8298    Input Parameters:
8299 +  mat - the matrix
8300 -  diag = the diagonal values, including ghost ones
8301 
8302    Level: developer
8303 
8304    Notes:
8305     Works only for MPIAIJ and MPIBAIJ matrices
8306 
8307 .seealso: MatDiagonalScale()
8308 @*/
8309 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8310 {
8311   PetscErrorCode ierr;
8312   PetscMPIInt    size;
8313 
8314   PetscFunctionBegin;
8315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8316   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8317   PetscValidType(mat,1);
8318 
8319   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8320   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8321   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8322   if (size == 1) {
8323     PetscInt n,m;
8324     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8325     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8326     if (m == n) {
8327       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8328     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8329   } else {
8330     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8331   }
8332   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8333   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8334   PetscFunctionReturn(0);
8335 }
8336 
8337 /*@
8338    MatGetInertia - Gets the inertia from a factored matrix
8339 
8340    Collective on Mat
8341 
8342    Input Parameter:
8343 .  mat - the matrix
8344 
8345    Output Parameters:
8346 +   nneg - number of negative eigenvalues
8347 .   nzero - number of zero eigenvalues
8348 -   npos - number of positive eigenvalues
8349 
8350    Level: advanced
8351 
8352    Notes:
8353     Matrix must have been factored by MatCholeskyFactor()
8354 
8355 
8356 @*/
8357 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8358 {
8359   PetscErrorCode ierr;
8360 
8361   PetscFunctionBegin;
8362   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8363   PetscValidType(mat,1);
8364   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8365   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8366   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8367   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8368   PetscFunctionReturn(0);
8369 }
8370 
8371 /* ----------------------------------------------------------------*/
8372 /*@C
8373    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8374 
8375    Neighbor-wise Collective on Mats
8376 
8377    Input Parameters:
8378 +  mat - the factored matrix
8379 -  b - the right-hand-side vectors
8380 
8381    Output Parameter:
8382 .  x - the result vectors
8383 
8384    Notes:
8385    The vectors b and x cannot be the same.  I.e., one cannot
8386    call MatSolves(A,x,x).
8387 
8388    Notes:
8389    Most users should employ the simplified KSP interface for linear solvers
8390    instead of working directly with matrix algebra routines such as this.
8391    See, e.g., KSPCreate().
8392 
8393    Level: developer
8394 
8395 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8396 @*/
8397 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8398 {
8399   PetscErrorCode ierr;
8400 
8401   PetscFunctionBegin;
8402   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8403   PetscValidType(mat,1);
8404   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8405   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8406   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8407 
8408   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8409   MatCheckPreallocated(mat,1);
8410   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8411   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8412   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8413   PetscFunctionReturn(0);
8414 }
8415 
8416 /*@
8417    MatIsSymmetric - Test whether a matrix is symmetric
8418 
8419    Collective on Mat
8420 
8421    Input Parameter:
8422 +  A - the matrix to test
8423 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8424 
8425    Output Parameters:
8426 .  flg - the result
8427 
8428    Notes:
8429     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8430 
8431    Level: intermediate
8432 
8433 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8434 @*/
8435 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8436 {
8437   PetscErrorCode ierr;
8438 
8439   PetscFunctionBegin;
8440   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8441   PetscValidBoolPointer(flg,2);
8442 
8443   if (!A->symmetric_set) {
8444     if (!A->ops->issymmetric) {
8445       MatType mattype;
8446       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8447       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8448     }
8449     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8450     if (!tol) {
8451       A->symmetric_set = PETSC_TRUE;
8452       A->symmetric     = *flg;
8453       if (A->symmetric) {
8454         A->structurally_symmetric_set = PETSC_TRUE;
8455         A->structurally_symmetric     = PETSC_TRUE;
8456       }
8457     }
8458   } else if (A->symmetric) {
8459     *flg = PETSC_TRUE;
8460   } else if (!tol) {
8461     *flg = PETSC_FALSE;
8462   } else {
8463     if (!A->ops->issymmetric) {
8464       MatType mattype;
8465       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8466       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8467     }
8468     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8469   }
8470   PetscFunctionReturn(0);
8471 }
8472 
8473 /*@
8474    MatIsHermitian - Test whether a matrix is Hermitian
8475 
8476    Collective on Mat
8477 
8478    Input Parameter:
8479 +  A - the matrix to test
8480 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8481 
8482    Output Parameters:
8483 .  flg - the result
8484 
8485    Level: intermediate
8486 
8487 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8488           MatIsSymmetricKnown(), MatIsSymmetric()
8489 @*/
8490 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8491 {
8492   PetscErrorCode ierr;
8493 
8494   PetscFunctionBegin;
8495   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8496   PetscValidBoolPointer(flg,2);
8497 
8498   if (!A->hermitian_set) {
8499     if (!A->ops->ishermitian) {
8500       MatType mattype;
8501       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8502       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8503     }
8504     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8505     if (!tol) {
8506       A->hermitian_set = PETSC_TRUE;
8507       A->hermitian     = *flg;
8508       if (A->hermitian) {
8509         A->structurally_symmetric_set = PETSC_TRUE;
8510         A->structurally_symmetric     = PETSC_TRUE;
8511       }
8512     }
8513   } else if (A->hermitian) {
8514     *flg = PETSC_TRUE;
8515   } else if (!tol) {
8516     *flg = PETSC_FALSE;
8517   } else {
8518     if (!A->ops->ishermitian) {
8519       MatType mattype;
8520       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8521       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8522     }
8523     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8524   }
8525   PetscFunctionReturn(0);
8526 }
8527 
8528 /*@
8529    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8530 
8531    Not Collective
8532 
8533    Input Parameter:
8534 .  A - the matrix to check
8535 
8536    Output Parameters:
8537 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8538 -  flg - the result
8539 
8540    Level: advanced
8541 
8542    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8543          if you want it explicitly checked
8544 
8545 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8546 @*/
8547 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8548 {
8549   PetscFunctionBegin;
8550   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8551   PetscValidPointer(set,2);
8552   PetscValidBoolPointer(flg,3);
8553   if (A->symmetric_set) {
8554     *set = PETSC_TRUE;
8555     *flg = A->symmetric;
8556   } else {
8557     *set = PETSC_FALSE;
8558   }
8559   PetscFunctionReturn(0);
8560 }
8561 
8562 /*@
8563    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8564 
8565    Not Collective
8566 
8567    Input Parameter:
8568 .  A - the matrix to check
8569 
8570    Output Parameters:
8571 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8572 -  flg - the result
8573 
8574    Level: advanced
8575 
8576    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8577          if you want it explicitly checked
8578 
8579 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8580 @*/
8581 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8582 {
8583   PetscFunctionBegin;
8584   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8585   PetscValidPointer(set,2);
8586   PetscValidBoolPointer(flg,3);
8587   if (A->hermitian_set) {
8588     *set = PETSC_TRUE;
8589     *flg = A->hermitian;
8590   } else {
8591     *set = PETSC_FALSE;
8592   }
8593   PetscFunctionReturn(0);
8594 }
8595 
8596 /*@
8597    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8598 
8599    Collective on Mat
8600 
8601    Input Parameter:
8602 .  A - the matrix to test
8603 
8604    Output Parameters:
8605 .  flg - the result
8606 
8607    Level: intermediate
8608 
8609 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8610 @*/
8611 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8612 {
8613   PetscErrorCode ierr;
8614 
8615   PetscFunctionBegin;
8616   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8617   PetscValidBoolPointer(flg,2);
8618   if (!A->structurally_symmetric_set) {
8619     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);
8620     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8621 
8622     A->structurally_symmetric_set = PETSC_TRUE;
8623   }
8624   *flg = A->structurally_symmetric;
8625   PetscFunctionReturn(0);
8626 }
8627 
8628 /*@
8629    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8630        to be communicated to other processors during the MatAssemblyBegin/End() process
8631 
8632     Not collective
8633 
8634    Input Parameter:
8635 .   vec - the vector
8636 
8637    Output Parameters:
8638 +   nstash   - the size of the stash
8639 .   reallocs - the number of additional mallocs incurred.
8640 .   bnstash   - the size of the block stash
8641 -   breallocs - the number of additional mallocs incurred.in the block stash
8642 
8643    Level: advanced
8644 
8645 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8646 
8647 @*/
8648 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8649 {
8650   PetscErrorCode ierr;
8651 
8652   PetscFunctionBegin;
8653   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8654   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8655   PetscFunctionReturn(0);
8656 }
8657 
8658 /*@C
8659    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8660      parallel layout
8661 
8662    Collective on Mat
8663 
8664    Input Parameter:
8665 .  mat - the matrix
8666 
8667    Output Parameter:
8668 +   right - (optional) vector that the matrix can be multiplied against
8669 -   left - (optional) vector that the matrix vector product can be stored in
8670 
8671    Notes:
8672     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().
8673 
8674   Notes:
8675     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8676 
8677   Level: advanced
8678 
8679 .seealso: MatCreate(), VecDestroy()
8680 @*/
8681 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8682 {
8683   PetscErrorCode ierr;
8684 
8685   PetscFunctionBegin;
8686   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8687   PetscValidType(mat,1);
8688   if (mat->ops->getvecs) {
8689     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8690   } else {
8691     PetscInt rbs,cbs;
8692     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8693     if (right) {
8694       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8695       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8696       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8697       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8698       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8699       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8700     }
8701     if (left) {
8702       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8703       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8704       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8705       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8706       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8707       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8708     }
8709   }
8710   PetscFunctionReturn(0);
8711 }
8712 
8713 /*@C
8714    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8715      with default values.
8716 
8717    Not Collective
8718 
8719    Input Parameters:
8720 .    info - the MatFactorInfo data structure
8721 
8722 
8723    Notes:
8724     The solvers are generally used through the KSP and PC objects, for example
8725           PCLU, PCILU, PCCHOLESKY, PCICC
8726 
8727    Level: developer
8728 
8729 .seealso: MatFactorInfo
8730 
8731     Developer Note: fortran interface is not autogenerated as the f90
8732     interface defintion cannot be generated correctly [due to MatFactorInfo]
8733 
8734 @*/
8735 
8736 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8737 {
8738   PetscErrorCode ierr;
8739 
8740   PetscFunctionBegin;
8741   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8742   PetscFunctionReturn(0);
8743 }
8744 
8745 /*@
8746    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8747 
8748    Collective on Mat
8749 
8750    Input Parameters:
8751 +  mat - the factored matrix
8752 -  is - the index set defining the Schur indices (0-based)
8753 
8754    Notes:
8755     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8756 
8757    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8758 
8759    Level: developer
8760 
8761 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8762           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8763 
8764 @*/
8765 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8766 {
8767   PetscErrorCode ierr,(*f)(Mat,IS);
8768 
8769   PetscFunctionBegin;
8770   PetscValidType(mat,1);
8771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8772   PetscValidType(is,2);
8773   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8774   PetscCheckSameComm(mat,1,is,2);
8775   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8776   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8777   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");
8778   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8779   ierr = (*f)(mat,is);CHKERRQ(ierr);
8780   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8781   PetscFunctionReturn(0);
8782 }
8783 
8784 /*@
8785   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8786 
8787    Logically Collective on Mat
8788 
8789    Input Parameters:
8790 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8791 .  S - location where to return the Schur complement, can be NULL
8792 -  status - the status of the Schur complement matrix, can be NULL
8793 
8794    Notes:
8795    You must call MatFactorSetSchurIS() before calling this routine.
8796 
8797    The routine provides a copy of the Schur matrix stored within the solver data structures.
8798    The caller must destroy the object when it is no longer needed.
8799    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8800 
8801    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)
8802 
8803    Developer Notes:
8804     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8805    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8806 
8807    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8808 
8809    Level: advanced
8810 
8811    References:
8812 
8813 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8814 @*/
8815 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8816 {
8817   PetscErrorCode ierr;
8818 
8819   PetscFunctionBegin;
8820   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8821   if (S) PetscValidPointer(S,2);
8822   if (status) PetscValidPointer(status,3);
8823   if (S) {
8824     PetscErrorCode (*f)(Mat,Mat*);
8825 
8826     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8827     if (f) {
8828       ierr = (*f)(F,S);CHKERRQ(ierr);
8829     } else {
8830       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8831     }
8832   }
8833   if (status) *status = F->schur_status;
8834   PetscFunctionReturn(0);
8835 }
8836 
8837 /*@
8838   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8839 
8840    Logically Collective on Mat
8841 
8842    Input Parameters:
8843 +  F - the factored matrix obtained by calling MatGetFactor()
8844 .  *S - location where to return the Schur complement, can be NULL
8845 -  status - the status of the Schur complement matrix, can be NULL
8846 
8847    Notes:
8848    You must call MatFactorSetSchurIS() before calling this routine.
8849 
8850    Schur complement mode is currently implemented for sequential matrices.
8851    The routine returns a the Schur Complement stored within the data strutures of the solver.
8852    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8853    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8854 
8855    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8856 
8857    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8858 
8859    Level: advanced
8860 
8861    References:
8862 
8863 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8864 @*/
8865 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8866 {
8867   PetscFunctionBegin;
8868   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8869   if (S) PetscValidPointer(S,2);
8870   if (status) PetscValidPointer(status,3);
8871   if (S) *S = F->schur;
8872   if (status) *status = F->schur_status;
8873   PetscFunctionReturn(0);
8874 }
8875 
8876 /*@
8877   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8878 
8879    Logically Collective on Mat
8880 
8881    Input Parameters:
8882 +  F - the factored matrix obtained by calling MatGetFactor()
8883 .  *S - location where the Schur complement is stored
8884 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8885 
8886    Notes:
8887 
8888    Level: advanced
8889 
8890    References:
8891 
8892 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8893 @*/
8894 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8895 {
8896   PetscErrorCode ierr;
8897 
8898   PetscFunctionBegin;
8899   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8900   if (S) {
8901     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8902     *S = NULL;
8903   }
8904   F->schur_status = status;
8905   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8906   PetscFunctionReturn(0);
8907 }
8908 
8909 /*@
8910   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8911 
8912    Logically Collective on Mat
8913 
8914    Input Parameters:
8915 +  F - the factored matrix obtained by calling MatGetFactor()
8916 .  rhs - location where the right hand side of the Schur complement system is stored
8917 -  sol - location where the solution of the Schur complement system has to be returned
8918 
8919    Notes:
8920    The sizes of the vectors should match the size of the Schur complement
8921 
8922    Must be called after MatFactorSetSchurIS()
8923 
8924    Level: advanced
8925 
8926    References:
8927 
8928 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8929 @*/
8930 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8931 {
8932   PetscErrorCode ierr;
8933 
8934   PetscFunctionBegin;
8935   PetscValidType(F,1);
8936   PetscValidType(rhs,2);
8937   PetscValidType(sol,3);
8938   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8939   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8940   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8941   PetscCheckSameComm(F,1,rhs,2);
8942   PetscCheckSameComm(F,1,sol,3);
8943   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8944   switch (F->schur_status) {
8945   case MAT_FACTOR_SCHUR_FACTORED:
8946     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8947     break;
8948   case MAT_FACTOR_SCHUR_INVERTED:
8949     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8950     break;
8951   default:
8952     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8953     break;
8954   }
8955   PetscFunctionReturn(0);
8956 }
8957 
8958 /*@
8959   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8960 
8961    Logically Collective on Mat
8962 
8963    Input Parameters:
8964 +  F - the factored matrix obtained by calling MatGetFactor()
8965 .  rhs - location where the right hand side of the Schur complement system is stored
8966 -  sol - location where the solution of the Schur complement system has to be returned
8967 
8968    Notes:
8969    The sizes of the vectors should match the size of the Schur complement
8970 
8971    Must be called after MatFactorSetSchurIS()
8972 
8973    Level: advanced
8974 
8975    References:
8976 
8977 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
8978 @*/
8979 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8980 {
8981   PetscErrorCode ierr;
8982 
8983   PetscFunctionBegin;
8984   PetscValidType(F,1);
8985   PetscValidType(rhs,2);
8986   PetscValidType(sol,3);
8987   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8988   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8989   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8990   PetscCheckSameComm(F,1,rhs,2);
8991   PetscCheckSameComm(F,1,sol,3);
8992   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8993   switch (F->schur_status) {
8994   case MAT_FACTOR_SCHUR_FACTORED:
8995     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
8996     break;
8997   case MAT_FACTOR_SCHUR_INVERTED:
8998     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
8999     break;
9000   default:
9001     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9002     break;
9003   }
9004   PetscFunctionReturn(0);
9005 }
9006 
9007 /*@
9008   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9009 
9010    Logically Collective on Mat
9011 
9012    Input Parameters:
9013 .  F - the factored matrix obtained by calling MatGetFactor()
9014 
9015    Notes:
9016     Must be called after MatFactorSetSchurIS().
9017 
9018    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9019 
9020    Level: advanced
9021 
9022    References:
9023 
9024 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9025 @*/
9026 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9027 {
9028   PetscErrorCode ierr;
9029 
9030   PetscFunctionBegin;
9031   PetscValidType(F,1);
9032   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9033   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9034   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9035   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9036   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9037   PetscFunctionReturn(0);
9038 }
9039 
9040 /*@
9041   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9042 
9043    Logically Collective on Mat
9044 
9045    Input Parameters:
9046 .  F - the factored matrix obtained by calling MatGetFactor()
9047 
9048    Notes:
9049     Must be called after MatFactorSetSchurIS().
9050 
9051    Level: advanced
9052 
9053    References:
9054 
9055 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9056 @*/
9057 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9058 {
9059   PetscErrorCode ierr;
9060 
9061   PetscFunctionBegin;
9062   PetscValidType(F,1);
9063   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9064   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9065   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9066   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9067   PetscFunctionReturn(0);
9068 }
9069 
9070 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9071 {
9072   Mat            AP;
9073   PetscErrorCode ierr;
9074 
9075   PetscFunctionBegin;
9076   ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr);
9077   ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr);
9078   ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr);
9079   ierr = MatDestroy(&AP);CHKERRQ(ierr);
9080   PetscFunctionReturn(0);
9081 }
9082 
9083 /*@
9084    MatPtAP - Creates the matrix product C = P^T * A * P
9085 
9086    Neighbor-wise Collective on Mat
9087 
9088    Input Parameters:
9089 +  A - the matrix
9090 .  P - the projection matrix
9091 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9092 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9093           if the result is a dense matrix this is irrelevent
9094 
9095    Output Parameters:
9096 .  C - the product matrix
9097 
9098    Notes:
9099    C will be created and must be destroyed by the user with MatDestroy().
9100 
9101    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9102 
9103    Level: intermediate
9104 
9105 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9106 @*/
9107 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9108 {
9109   PetscErrorCode ierr;
9110   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9111   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9112   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9113   PetscBool      sametype;
9114 
9115   PetscFunctionBegin;
9116   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9117   PetscValidType(A,1);
9118   MatCheckPreallocated(A,1);
9119   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9120   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9121   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9122   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9123   PetscValidType(P,2);
9124   MatCheckPreallocated(P,2);
9125   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9126   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9127 
9128   if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N);
9129   if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9130   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9131   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9132 
9133   if (scall == MAT_REUSE_MATRIX) {
9134     PetscValidPointer(*C,5);
9135     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9136 
9137     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9138     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9139     if ((*C)->ops->ptapnumeric) {
9140       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9141     } else {
9142       ierr = MatPtAP_Basic(A,P,scall,fill,C);
9143     }
9144     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9145     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9146     PetscFunctionReturn(0);
9147   }
9148 
9149   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9150   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9151 
9152   fA = A->ops->ptap;
9153   fP = P->ops->ptap;
9154   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9155   if (fP == fA && sametype) {
9156     ptap = fA;
9157   } else {
9158     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9159     char ptapname[256];
9160     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9161     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9162     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9163     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9164     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9165     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9166   }
9167 
9168   if (!ptap) ptap = MatPtAP_Basic;
9169   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9170   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9171   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9172   if (A->symmetric_set && A->symmetric) {
9173     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9174   }
9175   PetscFunctionReturn(0);
9176 }
9177 
9178 /*@
9179    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9180 
9181    Neighbor-wise Collective on Mat
9182 
9183    Input Parameters:
9184 +  A - the matrix
9185 -  P - the projection matrix
9186 
9187    Output Parameters:
9188 .  C - the product matrix
9189 
9190    Notes:
9191    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9192    the user using MatDeatroy().
9193 
9194    This routine is currently only implemented for pairs of AIJ matrices and classes
9195    which inherit from AIJ.  C will be of type MATAIJ.
9196 
9197    Level: intermediate
9198 
9199 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9200 @*/
9201 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9202 {
9203   PetscErrorCode ierr;
9204 
9205   PetscFunctionBegin;
9206   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9207   PetscValidType(A,1);
9208   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9209   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9210   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9211   PetscValidType(P,2);
9212   MatCheckPreallocated(P,2);
9213   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9214   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9215   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9216   PetscValidType(C,3);
9217   MatCheckPreallocated(C,3);
9218   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9219   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
9220   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9221   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9222   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
9223   MatCheckPreallocated(A,1);
9224 
9225   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9226   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9227   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9228   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9229   PetscFunctionReturn(0);
9230 }
9231 
9232 /*@
9233    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9234 
9235    Neighbor-wise Collective on Mat
9236 
9237    Input Parameters:
9238 +  A - the matrix
9239 -  P - the projection matrix
9240 
9241    Output Parameters:
9242 .  C - the (i,j) structure of the product matrix
9243 
9244    Notes:
9245    C will be created and must be destroyed by the user with MatDestroy().
9246 
9247    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9248    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9249    this (i,j) structure by calling MatPtAPNumeric().
9250 
9251    Level: intermediate
9252 
9253 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9254 @*/
9255 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9256 {
9257   PetscErrorCode ierr;
9258 
9259   PetscFunctionBegin;
9260   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9261   PetscValidType(A,1);
9262   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9263   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9264   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9265   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9266   PetscValidType(P,2);
9267   MatCheckPreallocated(P,2);
9268   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9269   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9270   PetscValidPointer(C,3);
9271 
9272   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9273   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9274   MatCheckPreallocated(A,1);
9275 
9276   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9277   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9278   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9279   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9280 
9281   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9282   PetscFunctionReturn(0);
9283 }
9284 
9285 /*@
9286    MatRARt - Creates the matrix product C = R * A * R^T
9287 
9288    Neighbor-wise Collective on Mat
9289 
9290    Input Parameters:
9291 +  A - the matrix
9292 .  R - the projection matrix
9293 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9294 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9295           if the result is a dense matrix this is irrelevent
9296 
9297    Output Parameters:
9298 .  C - the product matrix
9299 
9300    Notes:
9301    C will be created and must be destroyed by the user with MatDestroy().
9302 
9303    This routine is currently only implemented for pairs of AIJ matrices and classes
9304    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9305    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9306    We recommend using MatPtAP().
9307 
9308    Level: intermediate
9309 
9310 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9311 @*/
9312 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9313 {
9314   PetscErrorCode ierr;
9315 
9316   PetscFunctionBegin;
9317   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9318   PetscValidType(A,1);
9319   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9320   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9321   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9322   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9323   PetscValidType(R,2);
9324   MatCheckPreallocated(R,2);
9325   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9326   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9327   PetscValidPointer(C,3);
9328   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9329 
9330   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9331   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9332   MatCheckPreallocated(A,1);
9333 
9334   if (!A->ops->rart) {
9335     Mat Rt;
9336     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9337     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9338     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9339     PetscFunctionReturn(0);
9340   }
9341   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9342   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9343   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9344   PetscFunctionReturn(0);
9345 }
9346 
9347 /*@
9348    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9349 
9350    Neighbor-wise Collective on Mat
9351 
9352    Input Parameters:
9353 +  A - the matrix
9354 -  R - the projection matrix
9355 
9356    Output Parameters:
9357 .  C - the product matrix
9358 
9359    Notes:
9360    C must have been created by calling MatRARtSymbolic and must be destroyed by
9361    the user using MatDestroy().
9362 
9363    This routine is currently only implemented for pairs of AIJ matrices and classes
9364    which inherit from AIJ.  C will be of type MATAIJ.
9365 
9366    Level: intermediate
9367 
9368 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9369 @*/
9370 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9371 {
9372   PetscErrorCode ierr;
9373 
9374   PetscFunctionBegin;
9375   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9376   PetscValidType(A,1);
9377   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9378   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9379   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9380   PetscValidType(R,2);
9381   MatCheckPreallocated(R,2);
9382   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9383   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9384   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9385   PetscValidType(C,3);
9386   MatCheckPreallocated(C,3);
9387   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9388   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9389   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9390   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9391   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9392   MatCheckPreallocated(A,1);
9393 
9394   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9395   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9396   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9397   PetscFunctionReturn(0);
9398 }
9399 
9400 /*@
9401    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9402 
9403    Neighbor-wise Collective on Mat
9404 
9405    Input Parameters:
9406 +  A - the matrix
9407 -  R - the projection matrix
9408 
9409    Output Parameters:
9410 .  C - the (i,j) structure of the product matrix
9411 
9412    Notes:
9413    C will be created and must be destroyed by the user with MatDestroy().
9414 
9415    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9416    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9417    this (i,j) structure by calling MatRARtNumeric().
9418 
9419    Level: intermediate
9420 
9421 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9422 @*/
9423 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9424 {
9425   PetscErrorCode ierr;
9426 
9427   PetscFunctionBegin;
9428   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9429   PetscValidType(A,1);
9430   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9431   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9432   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9433   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9434   PetscValidType(R,2);
9435   MatCheckPreallocated(R,2);
9436   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9437   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9438   PetscValidPointer(C,3);
9439 
9440   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9441   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9442   MatCheckPreallocated(A,1);
9443   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9444   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9445   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9446 
9447   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9448   PetscFunctionReturn(0);
9449 }
9450 
9451 /*@
9452    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9453 
9454    Neighbor-wise Collective on Mat
9455 
9456    Input Parameters:
9457 +  A - the left matrix
9458 .  B - the right matrix
9459 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9460 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9461           if the result is a dense matrix this is irrelevent
9462 
9463    Output Parameters:
9464 .  C - the product matrix
9465 
9466    Notes:
9467    Unless scall is MAT_REUSE_MATRIX C will be created.
9468 
9469    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
9470    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9471 
9472    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9473    actually needed.
9474 
9475    If you have many matrices with the same non-zero structure to multiply, you
9476    should either
9477 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9478 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9479    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
9480    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9481 
9482    Level: intermediate
9483 
9484 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9485 @*/
9486 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9487 {
9488   PetscErrorCode ierr;
9489   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9490   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9491   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9492   Mat            T;
9493   PetscBool      istrans;
9494 
9495   PetscFunctionBegin;
9496   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9497   PetscValidType(A,1);
9498   MatCheckPreallocated(A,1);
9499   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9500   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9501   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9502   PetscValidType(B,2);
9503   MatCheckPreallocated(B,2);
9504   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9505   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9506   PetscValidPointer(C,3);
9507   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9508   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9509   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9510   if (istrans) {
9511     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9512     ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9513     PetscFunctionReturn(0);
9514   } else {
9515     ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9516     if (istrans) {
9517       ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9518       ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr);
9519       PetscFunctionReturn(0);
9520     }
9521   }
9522   if (scall == MAT_REUSE_MATRIX) {
9523     PetscValidPointer(*C,5);
9524     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9525     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9526     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9527     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9528     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9529     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9530     PetscFunctionReturn(0);
9531   }
9532   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9533   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9534 
9535   fA = A->ops->matmult;
9536   fB = B->ops->matmult;
9537   if (fB == fA && fB) mult = fB;
9538   else {
9539     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9540     char multname[256];
9541     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9542     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9543     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9544     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9545     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9546     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9547     if (!mult) {
9548       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr);
9549     }
9550     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9551   }
9552   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9553   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9554   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9555   PetscFunctionReturn(0);
9556 }
9557 
9558 /*@
9559    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9560    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9561 
9562    Neighbor-wise Collective on Mat
9563 
9564    Input Parameters:
9565 +  A - the left matrix
9566 .  B - the right matrix
9567 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9568       if C is a dense matrix this is irrelevent
9569 
9570    Output Parameters:
9571 .  C - the product matrix
9572 
9573    Notes:
9574    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9575    actually needed.
9576 
9577    This routine is currently implemented for
9578     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9579     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9580     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9581 
9582    Level: intermediate
9583 
9584    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9585      We should incorporate them into PETSc.
9586 
9587 .seealso: MatMatMult(), MatMatMultNumeric()
9588 @*/
9589 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9590 {
9591   PetscErrorCode ierr;
9592   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9593   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9594   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9595 
9596   PetscFunctionBegin;
9597   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9598   PetscValidType(A,1);
9599   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9600   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9601 
9602   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9603   PetscValidType(B,2);
9604   MatCheckPreallocated(B,2);
9605   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9606   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9607   PetscValidPointer(C,3);
9608 
9609   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9610   if (fill == PETSC_DEFAULT) fill = 2.0;
9611   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9612   MatCheckPreallocated(A,1);
9613 
9614   Asymbolic = A->ops->matmultsymbolic;
9615   Bsymbolic = B->ops->matmultsymbolic;
9616   if (Asymbolic == Bsymbolic) {
9617     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9618     symbolic = Bsymbolic;
9619   } else { /* dispatch based on the type of A and B */
9620     char symbolicname[256];
9621     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9622     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9623     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9624     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9625     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9626     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9627     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9628   }
9629   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9630   *C = NULL;
9631   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9632   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9633   PetscFunctionReturn(0);
9634 }
9635 
9636 /*@
9637    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9638    Call this routine after first calling MatMatMultSymbolic().
9639 
9640    Neighbor-wise Collective on Mat
9641 
9642    Input Parameters:
9643 +  A - the left matrix
9644 -  B - the right matrix
9645 
9646    Output Parameters:
9647 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9648 
9649    Notes:
9650    C must have been created with MatMatMultSymbolic().
9651 
9652    This routine is currently implemented for
9653     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9654     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9655     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9656 
9657    Level: intermediate
9658 
9659 .seealso: MatMatMult(), MatMatMultSymbolic()
9660 @*/
9661 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9662 {
9663   PetscErrorCode ierr;
9664 
9665   PetscFunctionBegin;
9666   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9667   PetscFunctionReturn(0);
9668 }
9669 
9670 /*@
9671    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9672 
9673    Neighbor-wise Collective on Mat
9674 
9675    Input Parameters:
9676 +  A - the left matrix
9677 .  B - the right matrix
9678 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9679 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9680 
9681    Output Parameters:
9682 .  C - the product matrix
9683 
9684    Notes:
9685    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9686 
9687    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9688 
9689   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9690    actually needed.
9691 
9692    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9693    and for pairs of MPIDense matrices.
9694 
9695    Options Database Keys:
9696 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9697                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9698                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9699 
9700    Level: intermediate
9701 
9702 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9703 @*/
9704 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9705 {
9706   PetscErrorCode ierr;
9707   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9708   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9709   Mat            T;
9710   PetscBool      istrans;
9711 
9712   PetscFunctionBegin;
9713   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9714   PetscValidType(A,1);
9715   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9716   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9717   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9718   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9719   PetscValidType(B,2);
9720   MatCheckPreallocated(B,2);
9721   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9722   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9723   PetscValidPointer(C,3);
9724   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9725   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9726   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9727   MatCheckPreallocated(A,1);
9728 
9729   ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9730   if (istrans) {
9731     ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9732     ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr);
9733     PetscFunctionReturn(0);
9734   }
9735   fA = A->ops->mattransposemult;
9736   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9737   fB = B->ops->mattransposemult;
9738   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9739   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9740 
9741   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9742   if (scall == MAT_INITIAL_MATRIX) {
9743     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9744     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9745     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9746   }
9747   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9748   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9749   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9750   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9751   PetscFunctionReturn(0);
9752 }
9753 
9754 /*@
9755    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9756 
9757    Neighbor-wise Collective on Mat
9758 
9759    Input Parameters:
9760 +  A - the left matrix
9761 .  B - the right matrix
9762 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9763 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9764 
9765    Output Parameters:
9766 .  C - the product matrix
9767 
9768    Notes:
9769    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9770 
9771    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9772 
9773   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9774    actually needed.
9775 
9776    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9777    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9778 
9779    Level: intermediate
9780 
9781 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9782 @*/
9783 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9784 {
9785   PetscErrorCode ierr;
9786   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9787   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9788   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9789   Mat            T;
9790   PetscBool      istrans;
9791 
9792   PetscFunctionBegin;
9793   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9794   PetscValidType(A,1);
9795   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9796   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9797   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9798   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9799   PetscValidType(B,2);
9800   MatCheckPreallocated(B,2);
9801   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9802   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9803   PetscValidPointer(C,3);
9804   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9805   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9806   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9807   MatCheckPreallocated(A,1);
9808 
9809   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9810   if (istrans) {
9811     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9812     ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9813     PetscFunctionReturn(0);
9814   }
9815   fA = A->ops->transposematmult;
9816   fB = B->ops->transposematmult;
9817   if (fB == fA && fA) transposematmult = fA;
9818   else {
9819     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9820     char multname[256];
9821     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9822     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9823     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9824     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9825     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9826     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9827     if (!transposematmult) {
9828       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr);
9829     }
9830     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9831   }
9832   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9833   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9834   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9835   PetscFunctionReturn(0);
9836 }
9837 
9838 /*@
9839    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9840 
9841    Neighbor-wise Collective on Mat
9842 
9843    Input Parameters:
9844 +  A - the left matrix
9845 .  B - the middle matrix
9846 .  C - the right matrix
9847 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9848 -  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
9849           if the result is a dense matrix this is irrelevent
9850 
9851    Output Parameters:
9852 .  D - the product matrix
9853 
9854    Notes:
9855    Unless scall is MAT_REUSE_MATRIX D will be created.
9856 
9857    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9858 
9859    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9860    actually needed.
9861 
9862    If you have many matrices with the same non-zero structure to multiply, you
9863    should use MAT_REUSE_MATRIX in all calls but the first or
9864 
9865    Level: intermediate
9866 
9867 .seealso: MatMatMult, MatPtAP()
9868 @*/
9869 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9870 {
9871   PetscErrorCode ierr;
9872   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9873   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9874   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9875   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9876 
9877   PetscFunctionBegin;
9878   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9879   PetscValidType(A,1);
9880   MatCheckPreallocated(A,1);
9881   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9882   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9883   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9884   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9885   PetscValidType(B,2);
9886   MatCheckPreallocated(B,2);
9887   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9888   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9889   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9890   PetscValidPointer(C,3);
9891   MatCheckPreallocated(C,3);
9892   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9893   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9894   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9895   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9896   if (scall == MAT_REUSE_MATRIX) {
9897     PetscValidPointer(*D,6);
9898     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9899     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9900     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9901     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9902     PetscFunctionReturn(0);
9903   }
9904   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9905   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9906 
9907   fA = A->ops->matmatmult;
9908   fB = B->ops->matmatmult;
9909   fC = C->ops->matmatmult;
9910   if (fA == fB && fA == fC) {
9911     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9912     mult = fA;
9913   } else {
9914     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9915     char multname[256];
9916     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9917     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9918     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9919     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9920     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9921     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9922     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9923     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9924     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9925   }
9926   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9927   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9928   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9929   PetscFunctionReturn(0);
9930 }
9931 
9932 /*@
9933    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9934 
9935    Collective on Mat
9936 
9937    Input Parameters:
9938 +  mat - the matrix
9939 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9940 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9941 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9942 
9943    Output Parameter:
9944 .  matredundant - redundant matrix
9945 
9946    Notes:
9947    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9948    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9949 
9950    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9951    calling it.
9952 
9953    Level: advanced
9954 
9955 
9956 .seealso: MatDestroy()
9957 @*/
9958 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9959 {
9960   PetscErrorCode ierr;
9961   MPI_Comm       comm;
9962   PetscMPIInt    size;
9963   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9964   Mat_Redundant  *redund=NULL;
9965   PetscSubcomm   psubcomm=NULL;
9966   MPI_Comm       subcomm_in=subcomm;
9967   Mat            *matseq;
9968   IS             isrow,iscol;
9969   PetscBool      newsubcomm=PETSC_FALSE;
9970 
9971   PetscFunctionBegin;
9972   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9973   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9974     PetscValidPointer(*matredundant,5);
9975     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9976   }
9977 
9978   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9979   if (size == 1 || nsubcomm == 1) {
9980     if (reuse == MAT_INITIAL_MATRIX) {
9981       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9982     } else {
9983       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");
9984       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9985     }
9986     PetscFunctionReturn(0);
9987   }
9988 
9989   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9990   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9991   MatCheckPreallocated(mat,1);
9992 
9993   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9994   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9995     /* create psubcomm, then get subcomm */
9996     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9997     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9998     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9999 
10000     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10001     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10002     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10003     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10004     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10005     newsubcomm = PETSC_TRUE;
10006     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10007   }
10008 
10009   /* get isrow, iscol and a local sequential matrix matseq[0] */
10010   if (reuse == MAT_INITIAL_MATRIX) {
10011     mloc_sub = PETSC_DECIDE;
10012     nloc_sub = PETSC_DECIDE;
10013     if (bs < 1) {
10014       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10015       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10016     } else {
10017       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10018       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10019     }
10020     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10021     rstart = rend - mloc_sub;
10022     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10023     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10024   } else { /* reuse == MAT_REUSE_MATRIX */
10025     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");
10026     /* retrieve subcomm */
10027     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10028     redund = (*matredundant)->redundant;
10029     isrow  = redund->isrow;
10030     iscol  = redund->iscol;
10031     matseq = redund->matseq;
10032   }
10033   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10034 
10035   /* get matredundant over subcomm */
10036   if (reuse == MAT_INITIAL_MATRIX) {
10037     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10038 
10039     /* create a supporting struct and attach it to C for reuse */
10040     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10041     (*matredundant)->redundant = redund;
10042     redund->isrow              = isrow;
10043     redund->iscol              = iscol;
10044     redund->matseq             = matseq;
10045     if (newsubcomm) {
10046       redund->subcomm          = subcomm;
10047     } else {
10048       redund->subcomm          = MPI_COMM_NULL;
10049     }
10050   } else {
10051     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10052   }
10053   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10054   PetscFunctionReturn(0);
10055 }
10056 
10057 /*@C
10058    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10059    a given 'mat' object. Each submatrix can span multiple procs.
10060 
10061    Collective on Mat
10062 
10063    Input Parameters:
10064 +  mat - the matrix
10065 .  subcomm - the subcommunicator obtained by com_split(comm)
10066 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10067 
10068    Output Parameter:
10069 .  subMat - 'parallel submatrices each spans a given subcomm
10070 
10071   Notes:
10072   The submatrix partition across processors is dictated by 'subComm' a
10073   communicator obtained by com_split(comm). The comm_split
10074   is not restriced to be grouped with consecutive original ranks.
10075 
10076   Due the comm_split() usage, the parallel layout of the submatrices
10077   map directly to the layout of the original matrix [wrt the local
10078   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10079   into the 'DiagonalMat' of the subMat, hence it is used directly from
10080   the subMat. However the offDiagMat looses some columns - and this is
10081   reconstructed with MatSetValues()
10082 
10083   Level: advanced
10084 
10085 
10086 .seealso: MatCreateSubMatrices()
10087 @*/
10088 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10089 {
10090   PetscErrorCode ierr;
10091   PetscMPIInt    commsize,subCommSize;
10092 
10093   PetscFunctionBegin;
10094   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10095   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10096   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10097 
10098   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");
10099   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10100   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10101   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10102   PetscFunctionReturn(0);
10103 }
10104 
10105 /*@
10106    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10107 
10108    Not Collective
10109 
10110    Input Arguments:
10111 +  mat - matrix to extract local submatrix from
10112 .  isrow - local row indices for submatrix
10113 -  iscol - local column indices for submatrix
10114 
10115    Output Arguments:
10116 .  submat - the submatrix
10117 
10118    Level: intermediate
10119 
10120    Notes:
10121    The submat should be returned with MatRestoreLocalSubMatrix().
10122 
10123    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10124    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10125 
10126    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10127    MatSetValuesBlockedLocal() will also be implemented.
10128 
10129    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10130    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10131 
10132 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10133 @*/
10134 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10135 {
10136   PetscErrorCode ierr;
10137 
10138   PetscFunctionBegin;
10139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10140   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10141   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10142   PetscCheckSameComm(isrow,2,iscol,3);
10143   PetscValidPointer(submat,4);
10144   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10145 
10146   if (mat->ops->getlocalsubmatrix) {
10147     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10148   } else {
10149     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10150   }
10151   PetscFunctionReturn(0);
10152 }
10153 
10154 /*@
10155    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10156 
10157    Not Collective
10158 
10159    Input Arguments:
10160    mat - matrix to extract local submatrix from
10161    isrow - local row indices for submatrix
10162    iscol - local column indices for submatrix
10163    submat - the submatrix
10164 
10165    Level: intermediate
10166 
10167 .seealso: MatGetLocalSubMatrix()
10168 @*/
10169 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10170 {
10171   PetscErrorCode ierr;
10172 
10173   PetscFunctionBegin;
10174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10175   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10176   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10177   PetscCheckSameComm(isrow,2,iscol,3);
10178   PetscValidPointer(submat,4);
10179   if (*submat) {
10180     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10181   }
10182 
10183   if (mat->ops->restorelocalsubmatrix) {
10184     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10185   } else {
10186     ierr = MatDestroy(submat);CHKERRQ(ierr);
10187   }
10188   *submat = NULL;
10189   PetscFunctionReturn(0);
10190 }
10191 
10192 /* --------------------------------------------------------*/
10193 /*@
10194    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10195 
10196    Collective on Mat
10197 
10198    Input Parameter:
10199 .  mat - the matrix
10200 
10201    Output Parameter:
10202 .  is - if any rows have zero diagonals this contains the list of them
10203 
10204    Level: developer
10205 
10206 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10207 @*/
10208 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10209 {
10210   PetscErrorCode ierr;
10211 
10212   PetscFunctionBegin;
10213   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10214   PetscValidType(mat,1);
10215   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10216   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10217 
10218   if (!mat->ops->findzerodiagonals) {
10219     Vec                diag;
10220     const PetscScalar *a;
10221     PetscInt          *rows;
10222     PetscInt           rStart, rEnd, r, nrow = 0;
10223 
10224     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10225     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10226     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10227     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10228     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10229     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10230     nrow = 0;
10231     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10232     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10233     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10234     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10235   } else {
10236     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10237   }
10238   PetscFunctionReturn(0);
10239 }
10240 
10241 /*@
10242    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10243 
10244    Collective on Mat
10245 
10246    Input Parameter:
10247 .  mat - the matrix
10248 
10249    Output Parameter:
10250 .  is - contains the list of rows with off block diagonal entries
10251 
10252    Level: developer
10253 
10254 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10255 @*/
10256 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10257 {
10258   PetscErrorCode ierr;
10259 
10260   PetscFunctionBegin;
10261   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10262   PetscValidType(mat,1);
10263   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10264   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10265 
10266   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);
10267   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10268   PetscFunctionReturn(0);
10269 }
10270 
10271 /*@C
10272   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10273 
10274   Collective on Mat
10275 
10276   Input Parameters:
10277 . mat - the matrix
10278 
10279   Output Parameters:
10280 . values - the block inverses in column major order (FORTRAN-like)
10281 
10282    Note:
10283    This routine is not available from Fortran.
10284 
10285   Level: advanced
10286 
10287 .seealso: MatInvertBockDiagonalMat
10288 @*/
10289 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10290 {
10291   PetscErrorCode ierr;
10292 
10293   PetscFunctionBegin;
10294   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10295   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10296   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10297   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10298   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10299   PetscFunctionReturn(0);
10300 }
10301 
10302 /*@C
10303   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10304 
10305   Collective on Mat
10306 
10307   Input Parameters:
10308 + mat - the matrix
10309 . nblocks - the number of blocks
10310 - bsizes - the size of each block
10311 
10312   Output Parameters:
10313 . values - the block inverses in column major order (FORTRAN-like)
10314 
10315    Note:
10316    This routine is not available from Fortran.
10317 
10318   Level: advanced
10319 
10320 .seealso: MatInvertBockDiagonal()
10321 @*/
10322 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10323 {
10324   PetscErrorCode ierr;
10325 
10326   PetscFunctionBegin;
10327   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10328   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10329   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10330   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
10331   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10332   PetscFunctionReturn(0);
10333 }
10334 
10335 /*@
10336   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10337 
10338   Collective on Mat
10339 
10340   Input Parameters:
10341 . A - the matrix
10342 
10343   Output Parameters:
10344 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10345 
10346   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10347 
10348   Level: advanced
10349 
10350 .seealso: MatInvertBockDiagonal()
10351 @*/
10352 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10353 {
10354   PetscErrorCode     ierr;
10355   const PetscScalar *vals;
10356   PetscInt          *dnnz;
10357   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10358 
10359   PetscFunctionBegin;
10360   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10361   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10362   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10363   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10364   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10365   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10366   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10367   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10368   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10369   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10370   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10371   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10372   for (i = rstart/bs; i < rend/bs; i++) {
10373     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10374   }
10375   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10376   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10377   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10378   PetscFunctionReturn(0);
10379 }
10380 
10381 /*@C
10382     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10383     via MatTransposeColoringCreate().
10384 
10385     Collective on MatTransposeColoring
10386 
10387     Input Parameter:
10388 .   c - coloring context
10389 
10390     Level: intermediate
10391 
10392 .seealso: MatTransposeColoringCreate()
10393 @*/
10394 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10395 {
10396   PetscErrorCode       ierr;
10397   MatTransposeColoring matcolor=*c;
10398 
10399   PetscFunctionBegin;
10400   if (!matcolor) PetscFunctionReturn(0);
10401   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10402 
10403   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10404   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10405   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10406   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10407   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10408   if (matcolor->brows>0) {
10409     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10410   }
10411   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10412   PetscFunctionReturn(0);
10413 }
10414 
10415 /*@C
10416     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10417     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10418     MatTransposeColoring to sparse B.
10419 
10420     Collective on MatTransposeColoring
10421 
10422     Input Parameters:
10423 +   B - sparse matrix B
10424 .   Btdense - symbolic dense matrix B^T
10425 -   coloring - coloring context created with MatTransposeColoringCreate()
10426 
10427     Output Parameter:
10428 .   Btdense - dense matrix B^T
10429 
10430     Level: advanced
10431 
10432      Notes:
10433     These are used internally for some implementations of MatRARt()
10434 
10435 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10436 
10437 @*/
10438 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10439 {
10440   PetscErrorCode ierr;
10441 
10442   PetscFunctionBegin;
10443   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10444   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10445   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10446 
10447   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10448   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10449   PetscFunctionReturn(0);
10450 }
10451 
10452 /*@C
10453     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10454     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10455     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10456     Csp from Cden.
10457 
10458     Collective on MatTransposeColoring
10459 
10460     Input Parameters:
10461 +   coloring - coloring context created with MatTransposeColoringCreate()
10462 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10463 
10464     Output Parameter:
10465 .   Csp - sparse matrix
10466 
10467     Level: advanced
10468 
10469      Notes:
10470     These are used internally for some implementations of MatRARt()
10471 
10472 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10473 
10474 @*/
10475 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10476 {
10477   PetscErrorCode ierr;
10478 
10479   PetscFunctionBegin;
10480   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10481   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10482   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10483 
10484   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10485   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10486   PetscFunctionReturn(0);
10487 }
10488 
10489 /*@C
10490    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10491 
10492    Collective on Mat
10493 
10494    Input Parameters:
10495 +  mat - the matrix product C
10496 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10497 
10498     Output Parameter:
10499 .   color - the new coloring context
10500 
10501     Level: intermediate
10502 
10503 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10504            MatTransColoringApplyDenToSp()
10505 @*/
10506 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10507 {
10508   MatTransposeColoring c;
10509   MPI_Comm             comm;
10510   PetscErrorCode       ierr;
10511 
10512   PetscFunctionBegin;
10513   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10514   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10515   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10516 
10517   c->ctype = iscoloring->ctype;
10518   if (mat->ops->transposecoloringcreate) {
10519     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10520   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10521 
10522   *color = c;
10523   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10524   PetscFunctionReturn(0);
10525 }
10526 
10527 /*@
10528       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10529         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10530         same, otherwise it will be larger
10531 
10532      Not Collective
10533 
10534   Input Parameter:
10535 .    A  - the matrix
10536 
10537   Output Parameter:
10538 .    state - the current state
10539 
10540   Notes:
10541     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10542          different matrices
10543 
10544   Level: intermediate
10545 
10546 @*/
10547 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10548 {
10549   PetscFunctionBegin;
10550   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10551   *state = mat->nonzerostate;
10552   PetscFunctionReturn(0);
10553 }
10554 
10555 /*@
10556       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10557                  matrices from each processor
10558 
10559     Collective
10560 
10561    Input Parameters:
10562 +    comm - the communicators the parallel matrix will live on
10563 .    seqmat - the input sequential matrices
10564 .    n - number of local columns (or PETSC_DECIDE)
10565 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10566 
10567    Output Parameter:
10568 .    mpimat - the parallel matrix generated
10569 
10570     Level: advanced
10571 
10572    Notes:
10573     The number of columns of the matrix in EACH processor MUST be the same.
10574 
10575 @*/
10576 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10577 {
10578   PetscErrorCode ierr;
10579 
10580   PetscFunctionBegin;
10581   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10582   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");
10583 
10584   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10585   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10586   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10587   PetscFunctionReturn(0);
10588 }
10589 
10590 /*@
10591      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10592                  ranks' ownership ranges.
10593 
10594     Collective on A
10595 
10596    Input Parameters:
10597 +    A   - the matrix to create subdomains from
10598 -    N   - requested number of subdomains
10599 
10600 
10601    Output Parameters:
10602 +    n   - number of subdomains resulting on this rank
10603 -    iss - IS list with indices of subdomains on this rank
10604 
10605     Level: advanced
10606 
10607     Notes:
10608     number of subdomains must be smaller than the communicator size
10609 @*/
10610 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10611 {
10612   MPI_Comm        comm,subcomm;
10613   PetscMPIInt     size,rank,color;
10614   PetscInt        rstart,rend,k;
10615   PetscErrorCode  ierr;
10616 
10617   PetscFunctionBegin;
10618   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10619   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10620   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10621   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);
10622   *n = 1;
10623   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10624   color = rank/k;
10625   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10626   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10627   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10628   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10629   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10630   PetscFunctionReturn(0);
10631 }
10632 
10633 /*@
10634    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10635 
10636    If the interpolation and restriction operators are the same, uses MatPtAP.
10637    If they are not the same, use MatMatMatMult.
10638 
10639    Once the coarse grid problem is constructed, correct for interpolation operators
10640    that are not of full rank, which can legitimately happen in the case of non-nested
10641    geometric multigrid.
10642 
10643    Input Parameters:
10644 +  restrct - restriction operator
10645 .  dA - fine grid matrix
10646 .  interpolate - interpolation operator
10647 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10648 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10649 
10650    Output Parameters:
10651 .  A - the Galerkin coarse matrix
10652 
10653    Options Database Key:
10654 .  -pc_mg_galerkin <both,pmat,mat,none>
10655 
10656    Level: developer
10657 
10658 .seealso: MatPtAP(), MatMatMatMult()
10659 @*/
10660 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10661 {
10662   PetscErrorCode ierr;
10663   IS             zerorows;
10664   Vec            diag;
10665 
10666   PetscFunctionBegin;
10667   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10668   /* Construct the coarse grid matrix */
10669   if (interpolate == restrct) {
10670     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10671   } else {
10672     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10673   }
10674 
10675   /* If the interpolation matrix is not of full rank, A will have zero rows.
10676      This can legitimately happen in the case of non-nested geometric multigrid.
10677      In that event, we set the rows of the matrix to the rows of the identity,
10678      ignoring the equations (as the RHS will also be zero). */
10679 
10680   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10681 
10682   if (zerorows != NULL) { /* if there are any zero rows */
10683     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10684     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10685     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10686     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10687     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10688     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10689   }
10690   PetscFunctionReturn(0);
10691 }
10692 
10693 /*@C
10694     MatSetOperation - Allows user to set a matrix operation for any matrix type
10695 
10696    Logically Collective on Mat
10697 
10698     Input Parameters:
10699 +   mat - the matrix
10700 .   op - the name of the operation
10701 -   f - the function that provides the operation
10702 
10703    Level: developer
10704 
10705     Usage:
10706 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10707 $      ierr = MatCreateXXX(comm,...&A);
10708 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10709 
10710     Notes:
10711     See the file include/petscmat.h for a complete list of matrix
10712     operations, which all have the form MATOP_<OPERATION>, where
10713     <OPERATION> is the name (in all capital letters) of the
10714     user interface routine (e.g., MatMult() -> MATOP_MULT).
10715 
10716     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10717     sequence as the usual matrix interface routines, since they
10718     are intended to be accessed via the usual matrix interface
10719     routines, e.g.,
10720 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10721 
10722     In particular each function MUST return an error code of 0 on success and
10723     nonzero on failure.
10724 
10725     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10726 
10727 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10728 @*/
10729 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10730 {
10731   PetscFunctionBegin;
10732   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10733   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10734     mat->ops->viewnative = mat->ops->view;
10735   }
10736   (((void(**)(void))mat->ops)[op]) = f;
10737   PetscFunctionReturn(0);
10738 }
10739 
10740 /*@C
10741     MatGetOperation - Gets a matrix operation for any matrix type.
10742 
10743     Not Collective
10744 
10745     Input Parameters:
10746 +   mat - the matrix
10747 -   op - the name of the operation
10748 
10749     Output Parameter:
10750 .   f - the function that provides the operation
10751 
10752     Level: developer
10753 
10754     Usage:
10755 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10756 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10757 
10758     Notes:
10759     See the file include/petscmat.h for a complete list of matrix
10760     operations, which all have the form MATOP_<OPERATION>, where
10761     <OPERATION> is the name (in all capital letters) of the
10762     user interface routine (e.g., MatMult() -> MATOP_MULT).
10763 
10764     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10765 
10766 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10767 @*/
10768 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10769 {
10770   PetscFunctionBegin;
10771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10772   *f = (((void (**)(void))mat->ops)[op]);
10773   PetscFunctionReturn(0);
10774 }
10775 
10776 /*@
10777     MatHasOperation - Determines whether the given matrix supports the particular
10778     operation.
10779 
10780    Not Collective
10781 
10782    Input Parameters:
10783 +  mat - the matrix
10784 -  op - the operation, for example, MATOP_GET_DIAGONAL
10785 
10786    Output Parameter:
10787 .  has - either PETSC_TRUE or PETSC_FALSE
10788 
10789    Level: advanced
10790 
10791    Notes:
10792    See the file include/petscmat.h for a complete list of matrix
10793    operations, which all have the form MATOP_<OPERATION>, where
10794    <OPERATION> is the name (in all capital letters) of the
10795    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10796 
10797 .seealso: MatCreateShell()
10798 @*/
10799 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10800 {
10801   PetscErrorCode ierr;
10802 
10803   PetscFunctionBegin;
10804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10805   PetscValidType(mat,1);
10806   PetscValidPointer(has,3);
10807   if (mat->ops->hasoperation) {
10808     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10809   } else {
10810     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10811     else {
10812       *has = PETSC_FALSE;
10813       if (op == MATOP_CREATE_SUBMATRIX) {
10814         PetscMPIInt size;
10815 
10816         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10817         if (size == 1) {
10818           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10819         }
10820       }
10821     }
10822   }
10823   PetscFunctionReturn(0);
10824 }
10825 
10826 /*@
10827     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10828     of the matrix are congruent
10829 
10830    Collective on mat
10831 
10832    Input Parameters:
10833 .  mat - the matrix
10834 
10835    Output Parameter:
10836 .  cong - either PETSC_TRUE or PETSC_FALSE
10837 
10838    Level: beginner
10839 
10840    Notes:
10841 
10842 .seealso: MatCreate(), MatSetSizes()
10843 @*/
10844 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10845 {
10846   PetscErrorCode ierr;
10847 
10848   PetscFunctionBegin;
10849   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10850   PetscValidType(mat,1);
10851   PetscValidPointer(cong,2);
10852   if (!mat->rmap || !mat->cmap) {
10853     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10854     PetscFunctionReturn(0);
10855   }
10856   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10857     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10858     if (*cong) mat->congruentlayouts = 1;
10859     else       mat->congruentlayouts = 0;
10860   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10861   PetscFunctionReturn(0);
10862 }
10863 
10864 /*@
10865     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
10866     e.g., matrx product of MatPtAP.
10867 
10868    Collective on mat
10869 
10870    Input Parameters:
10871 .  mat - the matrix
10872 
10873    Output Parameter:
10874 .  mat - the matrix with intermediate data structures released
10875 
10876    Level: advanced
10877 
10878    Notes:
10879 
10880 .seealso: MatPtAP(), MatMatMult()
10881 @*/
10882 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
10883 {
10884   PetscErrorCode ierr;
10885 
10886   PetscFunctionBegin;
10887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10888   PetscValidType(mat,1);
10889   if (mat->ops->freeintermediatedatastructures) {
10890     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
10891   }
10892   PetscFunctionReturn(0);
10893 }
10894