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