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