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