xref: /petsc/src/mat/interface/matrix.c (revision 116bdff65fed8fe543555730f89dc71bb7f8b1f2)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   x->assembled = PETSC_TRUE;
94   ierr         = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
95   PetscFunctionReturn(0);
96 }
97 
98 /*@
99    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
100 
101    Logically Collective on Mat
102 
103    Input Parameters:
104 .  mat - the factored matrix
105 
106    Output Parameter:
107 +  pivot - the pivot value computed
108 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
109          the share the matrix
110 
111    Level: advanced
112 
113    Notes:
114     This routine does not work for factorizations done with external packages.
115    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
116 
117    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
118 
119 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
120 @*/
121 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
122 {
123   PetscFunctionBegin;
124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
125   *pivot = mat->factorerror_zeropivot_value;
126   *row   = mat->factorerror_zeropivot_row;
127   PetscFunctionReturn(0);
128 }
129 
130 /*@
131    MatFactorGetError - gets the error code from a factorization
132 
133    Logically Collective on Mat
134 
135    Input Parameters:
136 .  mat - the factored matrix
137 
138    Output Parameter:
139 .  err  - the error code
140 
141    Level: advanced
142 
143    Notes:
144     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
145 
146 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
147 @*/
148 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
149 {
150   PetscFunctionBegin;
151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
152   *err = mat->factorerrortype;
153   PetscFunctionReturn(0);
154 }
155 
156 /*@
157    MatFactorClearError - clears the error code in a factorization
158 
159    Logically Collective on Mat
160 
161    Input Parameter:
162 .  mat - the factored matrix
163 
164    Level: developer
165 
166    Notes:
167     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
168 
169 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
170 @*/
171 PetscErrorCode MatFactorClearError(Mat mat)
172 {
173   PetscFunctionBegin;
174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
175   mat->factorerrortype             = MAT_FACTOR_NOERROR;
176   mat->factorerror_zeropivot_value = 0.0;
177   mat->factorerror_zeropivot_row   = 0;
178   PetscFunctionReturn(0);
179 }
180 
181 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
182 {
183   PetscErrorCode    ierr;
184   Vec               r,l;
185   const PetscScalar *al;
186   PetscInt          i,nz,gnz,N,n;
187 
188   PetscFunctionBegin;
189   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
190   if (!cols) { /* nonzero rows */
191     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
192     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
193     ierr = VecSet(l,0.0);CHKERRQ(ierr);
194     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
195     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
196     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
197   } else { /* nonzero columns */
198     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
199     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
200     ierr = VecSet(r,0.0);CHKERRQ(ierr);
201     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
202     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
203     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
204   }
205   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
206   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
207   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
208   if (gnz != N) {
209     PetscInt *nzr;
210     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
211     if (nz) {
212       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
213       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
214     }
215     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
216   } else *nonzero = NULL;
217   if (!cols) { /* nonzero rows */
218     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
219   } else {
220     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
221   }
222   ierr = VecDestroy(&l);CHKERRQ(ierr);
223   ierr = VecDestroy(&r);CHKERRQ(ierr);
224   PetscFunctionReturn(0);
225 }
226 
227 /*@
228       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
229 
230   Input Parameter:
231 .    A  - the matrix
232 
233   Output Parameter:
234 .    keptrows - the rows that are not completely zero
235 
236   Notes:
237     keptrows is set to NULL if all rows are nonzero.
238 
239   Level: intermediate
240 
241  @*/
242 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
243 {
244   PetscErrorCode ierr;
245 
246   PetscFunctionBegin;
247   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
248   PetscValidType(mat,1);
249   PetscValidPointer(keptrows,2);
250   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
251   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
252   if (!mat->ops->findnonzerorows) {
253     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
254   } else {
255     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
256   }
257   PetscFunctionReturn(0);
258 }
259 
260 /*@
261       MatFindZeroRows - Locate all rows that are completely zero in the matrix
262 
263   Input Parameter:
264 .    A  - the matrix
265 
266   Output Parameter:
267 .    zerorows - the rows that are completely zero
268 
269   Notes:
270     zerorows is set to NULL if no rows are zero.
271 
272   Level: intermediate
273 
274  @*/
275 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
276 {
277   PetscErrorCode ierr;
278   IS keptrows;
279   PetscInt m, n;
280 
281   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
282   PetscValidType(mat,1);
283 
284   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
285   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
286      In keeping with this convention, we set zerorows to NULL if there are no zero
287      rows. */
288   if (keptrows == NULL) {
289     *zerorows = NULL;
290   } else {
291     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
292     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
293     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
294   }
295   PetscFunctionReturn(0);
296 }
297 
298 /*@
299    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
300 
301    Not Collective
302 
303    Input Parameters:
304 .   A - the matrix
305 
306    Output Parameters:
307 .   a - the diagonal part (which is a SEQUENTIAL matrix)
308 
309    Notes:
310     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
311           Use caution, as the reference count on the returned matrix is not incremented and it is used as
312 	  part of the containing MPI Mat's normal operation.
313 
314    Level: advanced
315 
316 @*/
317 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
318 {
319   PetscErrorCode ierr;
320 
321   PetscFunctionBegin;
322   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
323   PetscValidType(A,1);
324   PetscValidPointer(a,3);
325   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
326   if (!A->ops->getdiagonalblock) {
327     PetscMPIInt size;
328     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
329     if (size == 1) {
330       *a = A;
331       PetscFunctionReturn(0);
332     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
333   }
334   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
335   PetscFunctionReturn(0);
336 }
337 
338 /*@
339    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
340 
341    Collective on Mat
342 
343    Input Parameters:
344 .  mat - the matrix
345 
346    Output Parameter:
347 .   trace - the sum of the diagonal entries
348 
349    Level: advanced
350 
351 @*/
352 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
353 {
354   PetscErrorCode ierr;
355   Vec            diag;
356 
357   PetscFunctionBegin;
358   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
359   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
360   ierr = VecSum(diag,trace);CHKERRQ(ierr);
361   ierr = VecDestroy(&diag);CHKERRQ(ierr);
362   PetscFunctionReturn(0);
363 }
364 
365 /*@
366    MatRealPart - Zeros out the imaginary part of the matrix
367 
368    Logically Collective on Mat
369 
370    Input Parameters:
371 .  mat - the matrix
372 
373    Level: advanced
374 
375 
376 .seealso: MatImaginaryPart()
377 @*/
378 PetscErrorCode MatRealPart(Mat mat)
379 {
380   PetscErrorCode ierr;
381 
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
384   PetscValidType(mat,1);
385   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
386   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
387   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
388   MatCheckPreallocated(mat,1);
389   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
391   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
392     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
393   }
394 #endif
395   PetscFunctionReturn(0);
396 }
397 
398 /*@C
399    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
400 
401    Collective on Mat
402 
403    Input Parameter:
404 .  mat - the matrix
405 
406    Output Parameters:
407 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
408 -   ghosts - the global indices of the ghost points
409 
410    Notes:
411     the nghosts and ghosts are suitable to pass into VecCreateGhost()
412 
413    Level: advanced
414 
415 @*/
416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
417 {
418   PetscErrorCode ierr;
419 
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
422   PetscValidType(mat,1);
423   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
424   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
425   if (!mat->ops->getghosts) {
426     if (nghosts) *nghosts = 0;
427     if (ghosts) *ghosts = 0;
428   } else {
429     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
430   }
431   PetscFunctionReturn(0);
432 }
433 
434 
435 /*@
436    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
437 
438    Logically Collective on Mat
439 
440    Input Parameters:
441 .  mat - the matrix
442 
443    Level: advanced
444 
445 
446 .seealso: MatRealPart()
447 @*/
448 PetscErrorCode MatImaginaryPart(Mat mat)
449 {
450   PetscErrorCode ierr;
451 
452   PetscFunctionBegin;
453   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
454   PetscValidType(mat,1);
455   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
456   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
457   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
458   MatCheckPreallocated(mat,1);
459   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
460 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
461   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
462     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
463   }
464 #endif
465   PetscFunctionReturn(0);
466 }
467 
468 /*@
469    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
470 
471    Not Collective
472 
473    Input Parameter:
474 .  mat - the matrix
475 
476    Output Parameters:
477 +  missing - is any diagonal missing
478 -  dd - first diagonal entry that is missing (optional) on this process
479 
480    Level: advanced
481 
482 
483 .seealso: MatRealPart()
484 @*/
485 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
486 {
487   PetscErrorCode ierr;
488 
489   PetscFunctionBegin;
490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
491   PetscValidType(mat,1);
492   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
493   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
494   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
495   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
496   PetscFunctionReturn(0);
497 }
498 
499 /*@C
500    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
501    for each row that you get to ensure that your application does
502    not bleed memory.
503 
504    Not Collective
505 
506    Input Parameters:
507 +  mat - the matrix
508 -  row - the row to get
509 
510    Output Parameters:
511 +  ncols -  if not NULL, the number of nonzeros in the row
512 .  cols - if not NULL, the column numbers
513 -  vals - if not NULL, the values
514 
515    Notes:
516    This routine is provided for people who need to have direct access
517    to the structure of a matrix.  We hope that we provide enough
518    high-level matrix routines that few users will need it.
519 
520    MatGetRow() always returns 0-based column indices, regardless of
521    whether the internal representation is 0-based (default) or 1-based.
522 
523    For better efficiency, set cols and/or vals to NULL if you do
524    not wish to extract these quantities.
525 
526    The user can only examine the values extracted with MatGetRow();
527    the values cannot be altered.  To change the matrix entries, one
528    must use MatSetValues().
529 
530    You can only have one call to MatGetRow() outstanding for a particular
531    matrix at a time, per processor. MatGetRow() can only obtain rows
532    associated with the given processor, it cannot get rows from the
533    other processors; for that we suggest using MatCreateSubMatrices(), then
534    MatGetRow() on the submatrix. The row index passed to MatGetRow()
535    is in the global number of rows.
536 
537    Fortran Notes:
538    The calling sequence from Fortran is
539 .vb
540    MatGetRow(matrix,row,ncols,cols,values,ierr)
541          Mat     matrix (input)
542          integer row    (input)
543          integer ncols  (output)
544          integer cols(maxcols) (output)
545          double precision (or double complex) values(maxcols) output
546 .ve
547    where maxcols >= maximum nonzeros in any row of the matrix.
548 
549 
550    Caution:
551    Do not try to change the contents of the output arrays (cols and vals).
552    In some cases, this may corrupt the matrix.
553 
554    Level: advanced
555 
556    Concepts: matrices^row access
557 
558 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
559 @*/
560 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
561 {
562   PetscErrorCode ierr;
563   PetscInt       incols;
564 
565   PetscFunctionBegin;
566   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
567   PetscValidType(mat,1);
568   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
569   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
570   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
571   MatCheckPreallocated(mat,1);
572   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
573   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
574   if (ncols) *ncols = incols;
575   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
576   PetscFunctionReturn(0);
577 }
578 
579 /*@
580    MatConjugate - replaces the matrix values with their complex conjugates
581 
582    Logically Collective on Mat
583 
584    Input Parameters:
585 .  mat - the matrix
586 
587    Level: advanced
588 
589 .seealso:  VecConjugate()
590 @*/
591 PetscErrorCode MatConjugate(Mat mat)
592 {
593 #if defined(PETSC_USE_COMPLEX)
594   PetscErrorCode ierr;
595 
596   PetscFunctionBegin;
597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
598   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
599   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
600   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
601 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
602   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
603     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
604   }
605 #endif
606   PetscFunctionReturn(0);
607 #else
608   return 0;
609 #endif
610 }
611 
612 /*@C
613    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
614 
615    Not Collective
616 
617    Input Parameters:
618 +  mat - the matrix
619 .  row - the row to get
620 .  ncols, cols - the number of nonzeros and their columns
621 -  vals - if nonzero the column values
622 
623    Notes:
624    This routine should be called after you have finished examining the entries.
625 
626    This routine zeros out ncols, cols, and vals. This is to prevent accidental
627    us of the array after it has been restored. If you pass NULL, it will
628    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
629 
630    Fortran Notes:
631    The calling sequence from Fortran is
632 .vb
633    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
634       Mat     matrix (input)
635       integer row    (input)
636       integer ncols  (output)
637       integer cols(maxcols) (output)
638       double precision (or double complex) values(maxcols) output
639 .ve
640    Where maxcols >= maximum nonzeros in any row of the matrix.
641 
642    In Fortran MatRestoreRow() MUST be called after MatGetRow()
643    before another call to MatGetRow() can be made.
644 
645    Level: advanced
646 
647 .seealso:  MatGetRow()
648 @*/
649 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
650 {
651   PetscErrorCode ierr;
652 
653   PetscFunctionBegin;
654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
655   if (ncols) PetscValidIntPointer(ncols,3);
656   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
657   if (!mat->ops->restorerow) PetscFunctionReturn(0);
658   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
659   if (ncols) *ncols = 0;
660   if (cols)  *cols = NULL;
661   if (vals)  *vals = NULL;
662   PetscFunctionReturn(0);
663 }
664 
665 /*@
666    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
667    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
668 
669    Not Collective
670 
671    Input Parameters:
672 +  mat - the matrix
673 
674    Notes:
675    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
676 
677    Level: advanced
678 
679    Concepts: matrices^row access
680 
681 .seealso: MatRestoreRowRowUpperTriangular()
682 @*/
683 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
684 {
685   PetscErrorCode ierr;
686 
687   PetscFunctionBegin;
688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
689   PetscValidType(mat,1);
690   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
691   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
692   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
693   MatCheckPreallocated(mat,1);
694   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
695   PetscFunctionReturn(0);
696 }
697 
698 /*@
699    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
700 
701    Not Collective
702 
703    Input Parameters:
704 +  mat - the matrix
705 
706    Notes:
707    This routine should be called after you have finished MatGetRow/MatRestoreRow().
708 
709 
710    Level: advanced
711 
712 .seealso:  MatGetRowUpperTriangular()
713 @*/
714 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
715 {
716   PetscErrorCode ierr;
717 
718   PetscFunctionBegin;
719   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
720   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
721   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
722   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
723   PetscFunctionReturn(0);
724 }
725 
726 /*@C
727    MatSetOptionsPrefix - Sets the prefix used for searching for all
728    Mat options in the database.
729 
730    Logically Collective on Mat
731 
732    Input Parameter:
733 +  A - the Mat context
734 -  prefix - the prefix to prepend to all option names
735 
736    Notes:
737    A hyphen (-) must NOT be given at the beginning of the prefix name.
738    The first character of all runtime options is AUTOMATICALLY the hyphen.
739 
740    Level: advanced
741 
742 .keywords: Mat, set, options, prefix, database
743 
744 .seealso: MatSetFromOptions()
745 @*/
746 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
747 {
748   PetscErrorCode ierr;
749 
750   PetscFunctionBegin;
751   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
752   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
753   PetscFunctionReturn(0);
754 }
755 
756 /*@C
757    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
758    Mat options in the database.
759 
760    Logically Collective on Mat
761 
762    Input Parameters:
763 +  A - the Mat context
764 -  prefix - the prefix to prepend to all option names
765 
766    Notes:
767    A hyphen (-) must NOT be given at the beginning of the prefix name.
768    The first character of all runtime options is AUTOMATICALLY the hyphen.
769 
770    Level: advanced
771 
772 .keywords: Mat, append, options, prefix, database
773 
774 .seealso: MatGetOptionsPrefix()
775 @*/
776 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
777 {
778   PetscErrorCode ierr;
779 
780   PetscFunctionBegin;
781   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
782   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
783   PetscFunctionReturn(0);
784 }
785 
786 /*@C
787    MatGetOptionsPrefix - Sets the prefix used for searching for all
788    Mat options in the database.
789 
790    Not Collective
791 
792    Input Parameter:
793 .  A - the Mat context
794 
795    Output Parameter:
796 .  prefix - pointer to the prefix string used
797 
798    Notes:
799     On the fortran side, the user should pass in a string 'prefix' of
800    sufficient length to hold the prefix.
801 
802    Level: advanced
803 
804 .keywords: Mat, get, options, prefix, database
805 
806 .seealso: MatAppendOptionsPrefix()
807 @*/
808 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
809 {
810   PetscErrorCode ierr;
811 
812   PetscFunctionBegin;
813   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
814   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
815   PetscFunctionReturn(0);
816 }
817 
818 /*@
819    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
820 
821    Collective on Mat
822 
823    Input Parameters:
824 .  A - the Mat context
825 
826    Notes:
827    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
828    Currently support MPIAIJ and SEQAIJ.
829 
830    Level: beginner
831 
832 .keywords: Mat, ResetPreallocation
833 
834 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
835 @*/
836 PetscErrorCode MatResetPreallocation(Mat A)
837 {
838   PetscErrorCode ierr;
839 
840   PetscFunctionBegin;
841   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
842   PetscValidType(A,1);
843   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
844   PetscFunctionReturn(0);
845 }
846 
847 
848 /*@
849    MatSetUp - Sets up the internal matrix data structures for the later use.
850 
851    Collective on Mat
852 
853    Input Parameters:
854 .  A - the Mat context
855 
856    Notes:
857    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
858 
859    If a suitable preallocation routine is used, this function does not need to be called.
860 
861    See the Performance chapter of the PETSc users manual for how to preallocate matrices
862 
863    Level: beginner
864 
865 .keywords: Mat, setup
866 
867 .seealso: MatCreate(), MatDestroy()
868 @*/
869 PetscErrorCode MatSetUp(Mat A)
870 {
871   PetscMPIInt    size;
872   PetscErrorCode ierr;
873 
874   PetscFunctionBegin;
875   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
876   if (!((PetscObject)A)->type_name) {
877     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
878     if (size == 1) {
879       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
880     } else {
881       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
882     }
883   }
884   if (!A->preallocated && A->ops->setup) {
885     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
886     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
887   }
888   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
889   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
890   A->preallocated = PETSC_TRUE;
891   PetscFunctionReturn(0);
892 }
893 
894 #if defined(PETSC_HAVE_SAWS)
895 #include <petscviewersaws.h>
896 #endif
897 /*@C
898    MatView - Visualizes a matrix object.
899 
900    Collective on Mat
901 
902    Input Parameters:
903 +  mat - the matrix
904 -  viewer - visualization context
905 
906   Notes:
907   The available visualization contexts include
908 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
909 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
910 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
911 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
912 
913    The user can open alternative visualization contexts with
914 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
915 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
916          specified file; corresponding input uses MatLoad()
917 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
918          an X window display
919 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
920          Currently only the sequential dense and AIJ
921          matrix types support the Socket viewer.
922 
923    The user can call PetscViewerPushFormat() to specify the output
924    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
925    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
926 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
927 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
928 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
929 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
930          format common among all matrix types
931 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
932          format (which is in many cases the same as the default)
933 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
934          size and structure (not the matrix entries)
935 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
936          the matrix structure
937 
938    Options Database Keys:
939 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
940 .  -mat_view ::ascii_info_detail - Prints more detailed info
941 .  -mat_view - Prints matrix in ASCII format
942 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
943 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
944 .  -display <name> - Sets display name (default is host)
945 .  -draw_pause <sec> - Sets number of seconds to pause after display
946 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
947 .  -viewer_socket_machine <machine> -
948 .  -viewer_socket_port <port> -
949 .  -mat_view binary - save matrix to file in binary format
950 -  -viewer_binary_filename <name> -
951    Level: beginner
952 
953    Notes:
954     see the manual page for MatLoad() for the exact format of the binary file when the binary
955       viewer is used.
956 
957       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
958       viewer is used.
959 
960       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
961       And then use the following mouse functions:
962           left mouse: zoom in
963           middle mouse: zoom out
964           right mouse: continue with the simulation
965 
966    Concepts: matrices^viewing
967    Concepts: matrices^plotting
968    Concepts: matrices^printing
969 
970 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
971           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
972 @*/
973 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
974 {
975   PetscErrorCode    ierr;
976   PetscInt          rows,cols,rbs,cbs;
977   PetscBool         iascii,ibinary;
978   PetscViewerFormat format;
979   PetscMPIInt       size;
980 #if defined(PETSC_HAVE_SAWS)
981   PetscBool         issaws;
982 #endif
983 
984   PetscFunctionBegin;
985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
986   PetscValidType(mat,1);
987   if (!viewer) {
988     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
989   }
990   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
991   PetscCheckSameComm(mat,1,viewer,2);
992   MatCheckPreallocated(mat,1);
993   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
994   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
995   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
996   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
997   if (ibinary) {
998     PetscBool mpiio;
999     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1000     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1001   }
1002 
1003   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1004   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1005   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1006     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1007   }
1008 
1009 #if defined(PETSC_HAVE_SAWS)
1010   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1011 #endif
1012   if (iascii) {
1013     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1014     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1015     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1016       MatNullSpace nullsp,transnullsp;
1017 
1018       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1019       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1020       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1021       if (rbs != 1 || cbs != 1) {
1022         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1023         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1024       } else {
1025         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1026       }
1027       if (mat->factortype) {
1028         MatSolverType solver;
1029         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1030         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1031       }
1032       if (mat->ops->getinfo) {
1033         MatInfo info;
1034         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1035         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1036         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1037       }
1038       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1039       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1040       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1041       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1042       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1043       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1044     }
1045 #if defined(PETSC_HAVE_SAWS)
1046   } else if (issaws) {
1047     PetscMPIInt rank;
1048 
1049     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1050     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1051     if (!((PetscObject)mat)->amsmem && !rank) {
1052       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1053     }
1054 #endif
1055   }
1056   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1057     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1058     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1059     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1060   } else if (mat->ops->view) {
1061     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1062     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1063     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1064   }
1065   if (iascii) {
1066     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1067     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1068     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1069       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1070     }
1071   }
1072   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1073   PetscFunctionReturn(0);
1074 }
1075 
1076 #if defined(PETSC_USE_DEBUG)
1077 #include <../src/sys/totalview/tv_data_display.h>
1078 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1079 {
1080   TV_add_row("Local rows", "int", &mat->rmap->n);
1081   TV_add_row("Local columns", "int", &mat->cmap->n);
1082   TV_add_row("Global rows", "int", &mat->rmap->N);
1083   TV_add_row("Global columns", "int", &mat->cmap->N);
1084   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1085   return TV_format_OK;
1086 }
1087 #endif
1088 
1089 /*@C
1090    MatLoad - Loads a matrix that has been stored in binary format
1091    with MatView().  The matrix format is determined from the options database.
1092    Generates a parallel MPI matrix if the communicator has more than one
1093    processor.  The default matrix type is AIJ.
1094 
1095    Collective on PetscViewer
1096 
1097    Input Parameters:
1098 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1099             or some related function before a call to MatLoad()
1100 -  viewer - binary file viewer, created with PetscViewerBinaryOpen()
1101 
1102    Options Database Keys:
1103    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1104    block size
1105 .    -matload_block_size <bs>
1106 
1107    Level: beginner
1108 
1109    Notes:
1110    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1111    Mat before calling this routine if you wish to set it from the options database.
1112 
1113    MatLoad() automatically loads into the options database any options
1114    given in the file filename.info where filename is the name of the file
1115    that was passed to the PetscViewerBinaryOpen(). The options in the info
1116    file will be ignored if you use the -viewer_binary_skip_info option.
1117 
1118    If the type or size of newmat is not set before a call to MatLoad, PETSc
1119    sets the default matrix type AIJ and sets the local and global sizes.
1120    If type and/or size is already set, then the same are used.
1121 
1122    In parallel, each processor can load a subset of rows (or the
1123    entire matrix).  This routine is especially useful when a large
1124    matrix is stored on disk and only part of it is desired on each
1125    processor.  For example, a parallel solver may access only some of
1126    the rows from each processor.  The algorithm used here reads
1127    relatively small blocks of data rather than reading the entire
1128    matrix and then subsetting it.
1129 
1130    Notes for advanced users:
1131    Most users should not need to know the details of the binary storage
1132    format, since MatLoad() and MatView() completely hide these details.
1133    But for anyone who's interested, the standard binary matrix storage
1134    format is
1135 
1136 $    int    MAT_FILE_CLASSID
1137 $    int    number of rows
1138 $    int    number of columns
1139 $    int    total number of nonzeros
1140 $    int    *number nonzeros in each row
1141 $    int    *column indices of all nonzeros (starting index is zero)
1142 $    PetscScalar *values of all nonzeros
1143 
1144    PETSc automatically does the byte swapping for
1145 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1146 linux, Windows and the paragon; thus if you write your own binary
1147 read/write routines you have to swap the bytes; see PetscBinaryRead()
1148 and PetscBinaryWrite() to see how this may be done.
1149 
1150 .keywords: matrix, load, binary, input
1151 
1152 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
1153 
1154  @*/
1155 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1156 {
1157   PetscErrorCode ierr;
1158   PetscBool      isbinary,flg;
1159 
1160   PetscFunctionBegin;
1161   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1162   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1163   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1164   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1165 
1166   if (!((PetscObject)newmat)->type_name) {
1167     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1168   }
1169 
1170   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1171   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1172   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1173   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1174 
1175   flg  = PETSC_FALSE;
1176   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1177   if (flg) {
1178     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1179     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1180   }
1181   flg  = PETSC_FALSE;
1182   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1183   if (flg) {
1184     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1185   }
1186   PetscFunctionReturn(0);
1187 }
1188 
1189 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1190 {
1191   PetscErrorCode ierr;
1192   Mat_Redundant  *redund = *redundant;
1193   PetscInt       i;
1194 
1195   PetscFunctionBegin;
1196   if (redund){
1197     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1198       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1199       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1200       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1201     } else {
1202       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1203       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1204       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1205       for (i=0; i<redund->nrecvs; i++) {
1206         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1207         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1208       }
1209       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1210     }
1211 
1212     if (redund->subcomm) {
1213       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1214     }
1215     ierr = PetscFree(redund);CHKERRQ(ierr);
1216   }
1217   PetscFunctionReturn(0);
1218 }
1219 
1220 /*@
1221    MatDestroy - Frees space taken by a matrix.
1222 
1223    Collective on Mat
1224 
1225    Input Parameter:
1226 .  A - the matrix
1227 
1228    Level: beginner
1229 
1230 @*/
1231 PetscErrorCode MatDestroy(Mat *A)
1232 {
1233   PetscErrorCode ierr;
1234 
1235   PetscFunctionBegin;
1236   if (!*A) PetscFunctionReturn(0);
1237   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1238   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1239 
1240   /* if memory was published with SAWs then destroy it */
1241   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1242   if ((*A)->ops->destroy) {
1243     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1244   }
1245 
1246   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1247   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1248   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1249   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1250   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1251   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1252   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1253   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1254   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1255   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1256   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1257   PetscFunctionReturn(0);
1258 }
1259 
1260 /*@C
1261    MatSetValues - Inserts or adds a block of values into a matrix.
1262    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1263    MUST be called after all calls to MatSetValues() have been completed.
1264 
1265    Not Collective
1266 
1267    Input Parameters:
1268 +  mat - the matrix
1269 .  v - a logically two-dimensional array of values
1270 .  m, idxm - the number of rows and their global indices
1271 .  n, idxn - the number of columns and their global indices
1272 -  addv - either ADD_VALUES or INSERT_VALUES, where
1273    ADD_VALUES adds values to any existing entries, and
1274    INSERT_VALUES replaces existing entries with new values
1275 
1276    Notes:
1277    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1278       MatSetUp() before using this routine
1279 
1280    By default the values, v, are row-oriented. See MatSetOption() for other options.
1281 
1282    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1283    options cannot be mixed without intervening calls to the assembly
1284    routines.
1285 
1286    MatSetValues() uses 0-based row and column numbers in Fortran
1287    as well as in C.
1288 
1289    Negative indices may be passed in idxm and idxn, these rows and columns are
1290    simply ignored. This allows easily inserting element stiffness matrices
1291    with homogeneous Dirchlet boundary conditions that you don't want represented
1292    in the matrix.
1293 
1294    Efficiency Alert:
1295    The routine MatSetValuesBlocked() may offer much better efficiency
1296    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1297 
1298    Level: beginner
1299 
1300    Developer Notes:
1301     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1302                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1303 
1304    Concepts: matrices^putting entries in
1305 
1306 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1307           InsertMode, INSERT_VALUES, ADD_VALUES
1308 @*/
1309 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1310 {
1311   PetscErrorCode ierr;
1312 #if defined(PETSC_USE_DEBUG)
1313   PetscInt       i,j;
1314 #endif
1315 
1316   PetscFunctionBeginHot;
1317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1318   PetscValidType(mat,1);
1319   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1320   PetscValidIntPointer(idxm,3);
1321   PetscValidIntPointer(idxn,5);
1322   PetscValidScalarPointer(v,6);
1323   MatCheckPreallocated(mat,1);
1324   if (mat->insertmode == NOT_SET_VALUES) {
1325     mat->insertmode = addv;
1326   }
1327 #if defined(PETSC_USE_DEBUG)
1328   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1329   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1330   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1331 
1332   for (i=0; i<m; i++) {
1333     for (j=0; j<n; j++) {
1334       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1335 #if defined(PETSC_USE_COMPLEX)
1336         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1337 #else
1338         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1339 #endif
1340     }
1341   }
1342 #endif
1343 
1344   if (mat->assembled) {
1345     mat->was_assembled = PETSC_TRUE;
1346     mat->assembled     = PETSC_FALSE;
1347   }
1348   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1349   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1350   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1351 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1352   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1353     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1354   }
1355 #endif
1356   PetscFunctionReturn(0);
1357 }
1358 
1359 
1360 /*@
1361    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1362         values into a matrix
1363 
1364    Not Collective
1365 
1366    Input Parameters:
1367 +  mat - the matrix
1368 .  row - the (block) row to set
1369 -  v - a logically two-dimensional array of values
1370 
1371    Notes:
1372    By the values, v, are column-oriented (for the block version) and sorted
1373 
1374    All the nonzeros in the row must be provided
1375 
1376    The matrix must have previously had its column indices set
1377 
1378    The row must belong to this process
1379 
1380    Level: intermediate
1381 
1382    Concepts: matrices^putting entries in
1383 
1384 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1385           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1386 @*/
1387 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1388 {
1389   PetscErrorCode ierr;
1390   PetscInt       globalrow;
1391 
1392   PetscFunctionBegin;
1393   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1394   PetscValidType(mat,1);
1395   PetscValidScalarPointer(v,2);
1396   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1397   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1398 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1399   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1400     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1401   }
1402 #endif
1403   PetscFunctionReturn(0);
1404 }
1405 
1406 /*@
1407    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1408         values into a matrix
1409 
1410    Not Collective
1411 
1412    Input Parameters:
1413 +  mat - the matrix
1414 .  row - the (block) row to set
1415 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1416 
1417    Notes:
1418    The values, v, are column-oriented for the block version.
1419 
1420    All the nonzeros in the row must be provided
1421 
1422    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1423 
1424    The row must belong to this process
1425 
1426    Level: advanced
1427 
1428    Concepts: matrices^putting entries in
1429 
1430 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1431           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1432 @*/
1433 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1434 {
1435   PetscErrorCode ierr;
1436 
1437   PetscFunctionBeginHot;
1438   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1439   PetscValidType(mat,1);
1440   MatCheckPreallocated(mat,1);
1441   PetscValidScalarPointer(v,2);
1442 #if defined(PETSC_USE_DEBUG)
1443   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1444   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1445 #endif
1446   mat->insertmode = INSERT_VALUES;
1447 
1448   if (mat->assembled) {
1449     mat->was_assembled = PETSC_TRUE;
1450     mat->assembled     = PETSC_FALSE;
1451   }
1452   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1453   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1454   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1455   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1456 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1457   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1458     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1459   }
1460 #endif
1461   PetscFunctionReturn(0);
1462 }
1463 
1464 /*@
1465    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1466      Using structured grid indexing
1467 
1468    Not Collective
1469 
1470    Input Parameters:
1471 +  mat - the matrix
1472 .  m - number of rows being entered
1473 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1474 .  n - number of columns being entered
1475 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1476 .  v - a logically two-dimensional array of values
1477 -  addv - either ADD_VALUES or INSERT_VALUES, where
1478    ADD_VALUES adds values to any existing entries, and
1479    INSERT_VALUES replaces existing entries with new values
1480 
1481    Notes:
1482    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1483 
1484    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1485    options cannot be mixed without intervening calls to the assembly
1486    routines.
1487 
1488    The grid coordinates are across the entire grid, not just the local portion
1489 
1490    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1491    as well as in C.
1492 
1493    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1494 
1495    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1496    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1497 
1498    The columns and rows in the stencil passed in MUST be contained within the
1499    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1500    if you create a DMDA with an overlap of one grid level and on a particular process its first
1501    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1502    first i index you can use in your column and row indices in MatSetStencil() is 5.
1503 
1504    In Fortran idxm and idxn should be declared as
1505 $     MatStencil idxm(4,m),idxn(4,n)
1506    and the values inserted using
1507 $    idxm(MatStencil_i,1) = i
1508 $    idxm(MatStencil_j,1) = j
1509 $    idxm(MatStencil_k,1) = k
1510 $    idxm(MatStencil_c,1) = c
1511    etc
1512 
1513    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1514    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1515    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1516    DM_BOUNDARY_PERIODIC boundary type.
1517 
1518    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1519    a single value per point) you can skip filling those indices.
1520 
1521    Inspired by the structured grid interface to the HYPRE package
1522    (http://www.llnl.gov/CASC/hypre)
1523 
1524    Efficiency Alert:
1525    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1526    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1527 
1528    Level: beginner
1529 
1530    Concepts: matrices^putting entries in
1531 
1532 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1533           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1534 @*/
1535 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1536 {
1537   PetscErrorCode ierr;
1538   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1539   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1540   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1541 
1542   PetscFunctionBegin;
1543   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1544   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1545   PetscValidType(mat,1);
1546   PetscValidIntPointer(idxm,3);
1547   PetscValidIntPointer(idxn,5);
1548   PetscValidScalarPointer(v,6);
1549 
1550   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1551     jdxm = buf; jdxn = buf+m;
1552   } else {
1553     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1554     jdxm = bufm; jdxn = bufn;
1555   }
1556   for (i=0; i<m; i++) {
1557     for (j=0; j<3-sdim; j++) dxm++;
1558     tmp = *dxm++ - starts[0];
1559     for (j=0; j<dim-1; j++) {
1560       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1561       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1562     }
1563     if (mat->stencil.noc) dxm++;
1564     jdxm[i] = tmp;
1565   }
1566   for (i=0; i<n; i++) {
1567     for (j=0; j<3-sdim; j++) dxn++;
1568     tmp = *dxn++ - starts[0];
1569     for (j=0; j<dim-1; j++) {
1570       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1571       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1572     }
1573     if (mat->stencil.noc) dxn++;
1574     jdxn[i] = tmp;
1575   }
1576   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1577   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1578   PetscFunctionReturn(0);
1579 }
1580 
1581 /*@
1582    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1583      Using structured grid indexing
1584 
1585    Not Collective
1586 
1587    Input Parameters:
1588 +  mat - the matrix
1589 .  m - number of rows being entered
1590 .  idxm - grid coordinates for matrix rows being entered
1591 .  n - number of columns being entered
1592 .  idxn - grid coordinates for matrix columns being entered
1593 .  v - a logically two-dimensional array of values
1594 -  addv - either ADD_VALUES or INSERT_VALUES, where
1595    ADD_VALUES adds values to any existing entries, and
1596    INSERT_VALUES replaces existing entries with new values
1597 
1598    Notes:
1599    By default the values, v, are row-oriented and unsorted.
1600    See MatSetOption() for other options.
1601 
1602    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1603    options cannot be mixed without intervening calls to the assembly
1604    routines.
1605 
1606    The grid coordinates are across the entire grid, not just the local portion
1607 
1608    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1609    as well as in C.
1610 
1611    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1612 
1613    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1614    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1615 
1616    The columns and rows in the stencil passed in MUST be contained within the
1617    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1618    if you create a DMDA with an overlap of one grid level and on a particular process its first
1619    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1620    first i index you can use in your column and row indices in MatSetStencil() is 5.
1621 
1622    In Fortran idxm and idxn should be declared as
1623 $     MatStencil idxm(4,m),idxn(4,n)
1624    and the values inserted using
1625 $    idxm(MatStencil_i,1) = i
1626 $    idxm(MatStencil_j,1) = j
1627 $    idxm(MatStencil_k,1) = k
1628    etc
1629 
1630    Negative indices may be passed in idxm and idxn, these rows and columns are
1631    simply ignored. This allows easily inserting element stiffness matrices
1632    with homogeneous Dirchlet boundary conditions that you don't want represented
1633    in the matrix.
1634 
1635    Inspired by the structured grid interface to the HYPRE package
1636    (http://www.llnl.gov/CASC/hypre)
1637 
1638    Level: beginner
1639 
1640    Concepts: matrices^putting entries in
1641 
1642 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1643           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1644           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1645 @*/
1646 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1647 {
1648   PetscErrorCode ierr;
1649   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1650   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1651   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1652 
1653   PetscFunctionBegin;
1654   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1656   PetscValidType(mat,1);
1657   PetscValidIntPointer(idxm,3);
1658   PetscValidIntPointer(idxn,5);
1659   PetscValidScalarPointer(v,6);
1660 
1661   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1662     jdxm = buf; jdxn = buf+m;
1663   } else {
1664     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1665     jdxm = bufm; jdxn = bufn;
1666   }
1667   for (i=0; i<m; i++) {
1668     for (j=0; j<3-sdim; j++) dxm++;
1669     tmp = *dxm++ - starts[0];
1670     for (j=0; j<sdim-1; j++) {
1671       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1672       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1673     }
1674     dxm++;
1675     jdxm[i] = tmp;
1676   }
1677   for (i=0; i<n; i++) {
1678     for (j=0; j<3-sdim; j++) dxn++;
1679     tmp = *dxn++ - starts[0];
1680     for (j=0; j<sdim-1; j++) {
1681       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1682       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1683     }
1684     dxn++;
1685     jdxn[i] = tmp;
1686   }
1687   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1688   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1689 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1690   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1691     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1692   }
1693 #endif
1694   PetscFunctionReturn(0);
1695 }
1696 
1697 /*@
1698    MatSetStencil - Sets the grid information for setting values into a matrix via
1699         MatSetValuesStencil()
1700 
1701    Not Collective
1702 
1703    Input Parameters:
1704 +  mat - the matrix
1705 .  dim - dimension of the grid 1, 2, or 3
1706 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1707 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1708 -  dof - number of degrees of freedom per node
1709 
1710 
1711    Inspired by the structured grid interface to the HYPRE package
1712    (www.llnl.gov/CASC/hyper)
1713 
1714    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1715    user.
1716 
1717    Level: beginner
1718 
1719    Concepts: matrices^putting entries in
1720 
1721 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1722           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1723 @*/
1724 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1725 {
1726   PetscInt i;
1727 
1728   PetscFunctionBegin;
1729   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1730   PetscValidIntPointer(dims,3);
1731   PetscValidIntPointer(starts,4);
1732 
1733   mat->stencil.dim = dim + (dof > 1);
1734   for (i=0; i<dim; i++) {
1735     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1736     mat->stencil.starts[i] = starts[dim-i-1];
1737   }
1738   mat->stencil.dims[dim]   = dof;
1739   mat->stencil.starts[dim] = 0;
1740   mat->stencil.noc         = (PetscBool)(dof == 1);
1741   PetscFunctionReturn(0);
1742 }
1743 
1744 /*@C
1745    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1746 
1747    Not Collective
1748 
1749    Input Parameters:
1750 +  mat - the matrix
1751 .  v - a logically two-dimensional array of values
1752 .  m, idxm - the number of block rows and their global block indices
1753 .  n, idxn - the number of block columns and their global block indices
1754 -  addv - either ADD_VALUES or INSERT_VALUES, where
1755    ADD_VALUES adds values to any existing entries, and
1756    INSERT_VALUES replaces existing entries with new values
1757 
1758    Notes:
1759    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1760    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1761 
1762    The m and n count the NUMBER of blocks in the row direction and column direction,
1763    NOT the total number of rows/columns; for example, if the block size is 2 and
1764    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1765    The values in idxm would be 1 2; that is the first index for each block divided by
1766    the block size.
1767 
1768    Note that you must call MatSetBlockSize() when constructing this matrix (before
1769    preallocating it).
1770 
1771    By default the values, v, are row-oriented, so the layout of
1772    v is the same as for MatSetValues(). See MatSetOption() for other options.
1773 
1774    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1775    options cannot be mixed without intervening calls to the assembly
1776    routines.
1777 
1778    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1779    as well as in C.
1780 
1781    Negative indices may be passed in idxm and idxn, these rows and columns are
1782    simply ignored. This allows easily inserting element stiffness matrices
1783    with homogeneous Dirchlet boundary conditions that you don't want represented
1784    in the matrix.
1785 
1786    Each time an entry is set within a sparse matrix via MatSetValues(),
1787    internal searching must be done to determine where to place the
1788    data in the matrix storage space.  By instead inserting blocks of
1789    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1790    reduced.
1791 
1792    Example:
1793 $   Suppose m=n=2 and block size(bs) = 2 The array is
1794 $
1795 $   1  2  | 3  4
1796 $   5  6  | 7  8
1797 $   - - - | - - -
1798 $   9  10 | 11 12
1799 $   13 14 | 15 16
1800 $
1801 $   v[] should be passed in like
1802 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1803 $
1804 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1805 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1806 
1807    Level: intermediate
1808 
1809    Concepts: matrices^putting entries in blocked
1810 
1811 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1812 @*/
1813 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1814 {
1815   PetscErrorCode ierr;
1816 
1817   PetscFunctionBeginHot;
1818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1819   PetscValidType(mat,1);
1820   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1821   PetscValidIntPointer(idxm,3);
1822   PetscValidIntPointer(idxn,5);
1823   PetscValidScalarPointer(v,6);
1824   MatCheckPreallocated(mat,1);
1825   if (mat->insertmode == NOT_SET_VALUES) {
1826     mat->insertmode = addv;
1827   }
1828 #if defined(PETSC_USE_DEBUG)
1829   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1830   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1831   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1832 #endif
1833 
1834   if (mat->assembled) {
1835     mat->was_assembled = PETSC_TRUE;
1836     mat->assembled     = PETSC_FALSE;
1837   }
1838   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1839   if (mat->ops->setvaluesblocked) {
1840     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1841   } else {
1842     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1843     PetscInt i,j,bs,cbs;
1844     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1845     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1846       iidxm = buf; iidxn = buf + m*bs;
1847     } else {
1848       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1849       iidxm = bufr; iidxn = bufc;
1850     }
1851     for (i=0; i<m; i++) {
1852       for (j=0; j<bs; j++) {
1853         iidxm[i*bs+j] = bs*idxm[i] + j;
1854       }
1855     }
1856     for (i=0; i<n; i++) {
1857       for (j=0; j<cbs; j++) {
1858         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1859       }
1860     }
1861     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1862     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1863   }
1864   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1865 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1866   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1867     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1868   }
1869 #endif
1870   PetscFunctionReturn(0);
1871 }
1872 
1873 /*@
1874    MatGetValues - Gets a block of values from a matrix.
1875 
1876    Not Collective; currently only returns a local block
1877 
1878    Input Parameters:
1879 +  mat - the matrix
1880 .  v - a logically two-dimensional array for storing the values
1881 .  m, idxm - the number of rows and their global indices
1882 -  n, idxn - the number of columns and their global indices
1883 
1884    Notes:
1885    The user must allocate space (m*n PetscScalars) for the values, v.
1886    The values, v, are then returned in a row-oriented format,
1887    analogous to that used by default in MatSetValues().
1888 
1889    MatGetValues() uses 0-based row and column numbers in
1890    Fortran as well as in C.
1891 
1892    MatGetValues() requires that the matrix has been assembled
1893    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1894    MatSetValues() and MatGetValues() CANNOT be made in succession
1895    without intermediate matrix assembly.
1896 
1897    Negative row or column indices will be ignored and those locations in v[] will be
1898    left unchanged.
1899 
1900    Level: advanced
1901 
1902    Concepts: matrices^accessing values
1903 
1904 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1905 @*/
1906 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1907 {
1908   PetscErrorCode ierr;
1909 
1910   PetscFunctionBegin;
1911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1912   PetscValidType(mat,1);
1913   if (!m || !n) PetscFunctionReturn(0);
1914   PetscValidIntPointer(idxm,3);
1915   PetscValidIntPointer(idxn,5);
1916   PetscValidScalarPointer(v,6);
1917   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1918   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1919   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1920   MatCheckPreallocated(mat,1);
1921 
1922   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1923   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1924   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1925   PetscFunctionReturn(0);
1926 }
1927 
1928 /*@
1929   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1930   the same size. Currently, this can only be called once and creates the given matrix.
1931 
1932   Not Collective
1933 
1934   Input Parameters:
1935 + mat - the matrix
1936 . nb - the number of blocks
1937 . bs - the number of rows (and columns) in each block
1938 . rows - a concatenation of the rows for each block
1939 - v - a concatenation of logically two-dimensional arrays of values
1940 
1941   Notes:
1942   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1943 
1944   Level: advanced
1945 
1946   Concepts: matrices^putting entries in
1947 
1948 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1949           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1950 @*/
1951 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1952 {
1953   PetscErrorCode ierr;
1954 
1955   PetscFunctionBegin;
1956   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1957   PetscValidType(mat,1);
1958   PetscValidScalarPointer(rows,4);
1959   PetscValidScalarPointer(v,5);
1960 #if defined(PETSC_USE_DEBUG)
1961   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1962 #endif
1963 
1964   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1965   if (mat->ops->setvaluesbatch) {
1966     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1967   } else {
1968     PetscInt b;
1969     for (b = 0; b < nb; ++b) {
1970       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1971     }
1972   }
1973   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1974   PetscFunctionReturn(0);
1975 }
1976 
1977 /*@
1978    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1979    the routine MatSetValuesLocal() to allow users to insert matrix entries
1980    using a local (per-processor) numbering.
1981 
1982    Not Collective
1983 
1984    Input Parameters:
1985 +  x - the matrix
1986 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1987 - cmapping - column mapping
1988 
1989    Level: intermediate
1990 
1991    Concepts: matrices^local to global mapping
1992    Concepts: local to global mapping^for matrices
1993 
1994 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1995 @*/
1996 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1997 {
1998   PetscErrorCode ierr;
1999 
2000   PetscFunctionBegin;
2001   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2002   PetscValidType(x,1);
2003   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2004   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2005 
2006   if (x->ops->setlocaltoglobalmapping) {
2007     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2008   } else {
2009     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2010     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2011   }
2012   PetscFunctionReturn(0);
2013 }
2014 
2015 
2016 /*@
2017    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2018 
2019    Not Collective
2020 
2021    Input Parameters:
2022 .  A - the matrix
2023 
2024    Output Parameters:
2025 + rmapping - row mapping
2026 - cmapping - column mapping
2027 
2028    Level: advanced
2029 
2030    Concepts: matrices^local to global mapping
2031    Concepts: local to global mapping^for matrices
2032 
2033 .seealso:  MatSetValuesLocal()
2034 @*/
2035 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2036 {
2037   PetscFunctionBegin;
2038   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2039   PetscValidType(A,1);
2040   if (rmapping) PetscValidPointer(rmapping,2);
2041   if (cmapping) PetscValidPointer(cmapping,3);
2042   if (rmapping) *rmapping = A->rmap->mapping;
2043   if (cmapping) *cmapping = A->cmap->mapping;
2044   PetscFunctionReturn(0);
2045 }
2046 
2047 /*@
2048    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2049 
2050    Not Collective
2051 
2052    Input Parameters:
2053 .  A - the matrix
2054 
2055    Output Parameters:
2056 + rmap - row layout
2057 - cmap - column layout
2058 
2059    Level: advanced
2060 
2061 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2062 @*/
2063 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2064 {
2065   PetscFunctionBegin;
2066   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2067   PetscValidType(A,1);
2068   if (rmap) PetscValidPointer(rmap,2);
2069   if (cmap) PetscValidPointer(cmap,3);
2070   if (rmap) *rmap = A->rmap;
2071   if (cmap) *cmap = A->cmap;
2072   PetscFunctionReturn(0);
2073 }
2074 
2075 /*@C
2076    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2077    using a local ordering of the nodes.
2078 
2079    Not Collective
2080 
2081    Input Parameters:
2082 +  mat - the matrix
2083 .  nrow, irow - number of rows and their local indices
2084 .  ncol, icol - number of columns and their local indices
2085 .  y -  a logically two-dimensional array of values
2086 -  addv - either INSERT_VALUES or ADD_VALUES, where
2087    ADD_VALUES adds values to any existing entries, and
2088    INSERT_VALUES replaces existing entries with new values
2089 
2090    Notes:
2091    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2092       MatSetUp() before using this routine
2093 
2094    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2095 
2096    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2097    options cannot be mixed without intervening calls to the assembly
2098    routines.
2099 
2100    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2101    MUST be called after all calls to MatSetValuesLocal() have been completed.
2102 
2103    Level: intermediate
2104 
2105    Concepts: matrices^putting entries in with local numbering
2106 
2107    Developer Notes:
2108     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2109                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2110 
2111 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2112            MatSetValueLocal()
2113 @*/
2114 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2115 {
2116   PetscErrorCode ierr;
2117 
2118   PetscFunctionBeginHot;
2119   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2120   PetscValidType(mat,1);
2121   MatCheckPreallocated(mat,1);
2122   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2123   PetscValidIntPointer(irow,3);
2124   PetscValidIntPointer(icol,5);
2125   PetscValidScalarPointer(y,6);
2126   if (mat->insertmode == NOT_SET_VALUES) {
2127     mat->insertmode = addv;
2128   }
2129 #if defined(PETSC_USE_DEBUG)
2130   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2131   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2132   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2133 #endif
2134 
2135   if (mat->assembled) {
2136     mat->was_assembled = PETSC_TRUE;
2137     mat->assembled     = PETSC_FALSE;
2138   }
2139   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2140   if (mat->ops->setvalueslocal) {
2141     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2142   } else {
2143     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2144     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2145       irowm = buf; icolm = buf+nrow;
2146     } else {
2147       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2148       irowm = bufr; icolm = bufc;
2149     }
2150     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2151     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2152     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2153     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2154   }
2155   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2156 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2157   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2158     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2159   }
2160 #endif
2161   PetscFunctionReturn(0);
2162 }
2163 
2164 /*@C
2165    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2166    using a local ordering of the nodes a block at a time.
2167 
2168    Not Collective
2169 
2170    Input Parameters:
2171 +  x - the matrix
2172 .  nrow, irow - number of rows and their local indices
2173 .  ncol, icol - number of columns and their local indices
2174 .  y -  a logically two-dimensional array of values
2175 -  addv - either INSERT_VALUES or ADD_VALUES, where
2176    ADD_VALUES adds values to any existing entries, and
2177    INSERT_VALUES replaces existing entries with new values
2178 
2179    Notes:
2180    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2181       MatSetUp() before using this routine
2182 
2183    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2184       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2185 
2186    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2187    options cannot be mixed without intervening calls to the assembly
2188    routines.
2189 
2190    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2191    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2192 
2193    Level: intermediate
2194 
2195    Developer Notes:
2196     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2197                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2198 
2199    Concepts: matrices^putting blocked values in with local numbering
2200 
2201 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2202            MatSetValuesLocal(),  MatSetValuesBlocked()
2203 @*/
2204 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2205 {
2206   PetscErrorCode ierr;
2207 
2208   PetscFunctionBeginHot;
2209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2210   PetscValidType(mat,1);
2211   MatCheckPreallocated(mat,1);
2212   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2213   PetscValidIntPointer(irow,3);
2214   PetscValidIntPointer(icol,5);
2215   PetscValidScalarPointer(y,6);
2216   if (mat->insertmode == NOT_SET_VALUES) {
2217     mat->insertmode = addv;
2218   }
2219 #if defined(PETSC_USE_DEBUG)
2220   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2221   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2222   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2223 #endif
2224 
2225   if (mat->assembled) {
2226     mat->was_assembled = PETSC_TRUE;
2227     mat->assembled     = PETSC_FALSE;
2228   }
2229   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2230   if (mat->ops->setvaluesblockedlocal) {
2231     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2232   } else {
2233     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2234     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2235       irowm = buf; icolm = buf + nrow;
2236     } else {
2237       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2238       irowm = bufr; icolm = bufc;
2239     }
2240     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2241     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2242     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2243     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2244   }
2245   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2246 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2247   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2248     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2249   }
2250 #endif
2251   PetscFunctionReturn(0);
2252 }
2253 
2254 /*@
2255    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2256 
2257    Collective on Mat and Vec
2258 
2259    Input Parameters:
2260 +  mat - the matrix
2261 -  x   - the vector to be multiplied
2262 
2263    Output Parameters:
2264 .  y - the result
2265 
2266    Notes:
2267    The vectors x and y cannot be the same.  I.e., one cannot
2268    call MatMult(A,y,y).
2269 
2270    Level: developer
2271 
2272    Concepts: matrix-vector product
2273 
2274 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2275 @*/
2276 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2277 {
2278   PetscErrorCode ierr;
2279 
2280   PetscFunctionBegin;
2281   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2282   PetscValidType(mat,1);
2283   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2284   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2285 
2286   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2287   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2288   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2289   MatCheckPreallocated(mat,1);
2290 
2291   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2292   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2293   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2294   PetscFunctionReturn(0);
2295 }
2296 
2297 /* --------------------------------------------------------*/
2298 /*@
2299    MatMult - Computes the matrix-vector product, y = Ax.
2300 
2301    Neighbor-wise Collective on Mat and Vec
2302 
2303    Input Parameters:
2304 +  mat - the matrix
2305 -  x   - the vector to be multiplied
2306 
2307    Output Parameters:
2308 .  y - the result
2309 
2310    Notes:
2311    The vectors x and y cannot be the same.  I.e., one cannot
2312    call MatMult(A,y,y).
2313 
2314    Level: beginner
2315 
2316    Concepts: matrix-vector product
2317 
2318 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2319 @*/
2320 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2321 {
2322   PetscErrorCode ierr;
2323 
2324   PetscFunctionBegin;
2325   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2326   PetscValidType(mat,1);
2327   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2328   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2329   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2330   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2331   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2332 #if !defined(PETSC_HAVE_CONSTRAINTS)
2333   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2334   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2335   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2336 #endif
2337   VecLocked(y,3);
2338   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2339   MatCheckPreallocated(mat,1);
2340 
2341   ierr = VecLockPush(x);CHKERRQ(ierr);
2342   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2343   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2344   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2345   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2346   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2347   ierr = VecLockPop(x);CHKERRQ(ierr);
2348   PetscFunctionReturn(0);
2349 }
2350 
2351 /*@
2352    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2353 
2354    Neighbor-wise Collective on Mat and Vec
2355 
2356    Input Parameters:
2357 +  mat - the matrix
2358 -  x   - the vector to be multiplied
2359 
2360    Output Parameters:
2361 .  y - the result
2362 
2363    Notes:
2364    The vectors x and y cannot be the same.  I.e., one cannot
2365    call MatMultTranspose(A,y,y).
2366 
2367    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2368    use MatMultHermitianTranspose()
2369 
2370    Level: beginner
2371 
2372    Concepts: matrix vector product^transpose
2373 
2374 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2375 @*/
2376 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2377 {
2378   PetscErrorCode ierr;
2379 
2380   PetscFunctionBegin;
2381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2382   PetscValidType(mat,1);
2383   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2384   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2385 
2386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2388   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2389 #if !defined(PETSC_HAVE_CONSTRAINTS)
2390   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2391   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2392 #endif
2393   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2394   MatCheckPreallocated(mat,1);
2395 
2396   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2397   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2398   ierr = VecLockPush(x);CHKERRQ(ierr);
2399   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2400   ierr = VecLockPop(x);CHKERRQ(ierr);
2401   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2402   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2403   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2404   PetscFunctionReturn(0);
2405 }
2406 
2407 /*@
2408    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2409 
2410    Neighbor-wise Collective on Mat and Vec
2411 
2412    Input Parameters:
2413 +  mat - the matrix
2414 -  x   - the vector to be multilplied
2415 
2416    Output Parameters:
2417 .  y - the result
2418 
2419    Notes:
2420    The vectors x and y cannot be the same.  I.e., one cannot
2421    call MatMultHermitianTranspose(A,y,y).
2422 
2423    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2424 
2425    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2426 
2427    Level: beginner
2428 
2429    Concepts: matrix vector product^transpose
2430 
2431 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2432 @*/
2433 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2434 {
2435   PetscErrorCode ierr;
2436   Vec            w;
2437 
2438   PetscFunctionBegin;
2439   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2440   PetscValidType(mat,1);
2441   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2442   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2443 
2444   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2445   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2446   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2447 #if !defined(PETSC_HAVE_CONSTRAINTS)
2448   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2449   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2450 #endif
2451   MatCheckPreallocated(mat,1);
2452 
2453   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2454   if (mat->ops->multhermitiantranspose) {
2455     ierr = VecLockPush(x);CHKERRQ(ierr);
2456     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2457     ierr = VecLockPop(x);CHKERRQ(ierr);
2458   } else {
2459     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2460     ierr = VecCopy(x,w);CHKERRQ(ierr);
2461     ierr = VecConjugate(w);CHKERRQ(ierr);
2462     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2463     ierr = VecDestroy(&w);CHKERRQ(ierr);
2464     ierr = VecConjugate(y);CHKERRQ(ierr);
2465   }
2466   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2467   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2468   PetscFunctionReturn(0);
2469 }
2470 
2471 /*@
2472     MatMultAdd -  Computes v3 = v2 + A * v1.
2473 
2474     Neighbor-wise Collective on Mat and Vec
2475 
2476     Input Parameters:
2477 +   mat - the matrix
2478 -   v1, v2 - the vectors
2479 
2480     Output Parameters:
2481 .   v3 - the result
2482 
2483     Notes:
2484     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2485     call MatMultAdd(A,v1,v2,v1).
2486 
2487     Level: beginner
2488 
2489     Concepts: matrix vector product^addition
2490 
2491 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2492 @*/
2493 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2494 {
2495   PetscErrorCode ierr;
2496 
2497   PetscFunctionBegin;
2498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2499   PetscValidType(mat,1);
2500   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2501   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2502   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2503 
2504   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2505   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2506   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2507   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2508      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2509   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2510   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2511   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2512   MatCheckPreallocated(mat,1);
2513 
2514   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2515   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2516   ierr = VecLockPush(v1);CHKERRQ(ierr);
2517   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2518   ierr = VecLockPop(v1);CHKERRQ(ierr);
2519   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2520   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2521   PetscFunctionReturn(0);
2522 }
2523 
2524 /*@
2525    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2526 
2527    Neighbor-wise Collective on Mat and Vec
2528 
2529    Input Parameters:
2530 +  mat - the matrix
2531 -  v1, v2 - the vectors
2532 
2533    Output Parameters:
2534 .  v3 - the result
2535 
2536    Notes:
2537    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2538    call MatMultTransposeAdd(A,v1,v2,v1).
2539 
2540    Level: beginner
2541 
2542    Concepts: matrix vector product^transpose and addition
2543 
2544 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2545 @*/
2546 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2547 {
2548   PetscErrorCode ierr;
2549 
2550   PetscFunctionBegin;
2551   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2552   PetscValidType(mat,1);
2553   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2554   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2555   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2556 
2557   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2558   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2559   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2560   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2561   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2562   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2563   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2564   MatCheckPreallocated(mat,1);
2565 
2566   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2567   ierr = VecLockPush(v1);CHKERRQ(ierr);
2568   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2569   ierr = VecLockPop(v1);CHKERRQ(ierr);
2570   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2571   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2572   PetscFunctionReturn(0);
2573 }
2574 
2575 /*@
2576    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2577 
2578    Neighbor-wise Collective on Mat and Vec
2579 
2580    Input Parameters:
2581 +  mat - the matrix
2582 -  v1, v2 - the vectors
2583 
2584    Output Parameters:
2585 .  v3 - the result
2586 
2587    Notes:
2588    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2589    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2590 
2591    Level: beginner
2592 
2593    Concepts: matrix vector product^transpose and addition
2594 
2595 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2596 @*/
2597 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2598 {
2599   PetscErrorCode ierr;
2600 
2601   PetscFunctionBegin;
2602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2603   PetscValidType(mat,1);
2604   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2605   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2606   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2607 
2608   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2609   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2610   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2611   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2612   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2613   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2614   MatCheckPreallocated(mat,1);
2615 
2616   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2617   ierr = VecLockPush(v1);CHKERRQ(ierr);
2618   if (mat->ops->multhermitiantransposeadd) {
2619     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2620   } else {
2621     Vec w,z;
2622     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2623     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2624     ierr = VecConjugate(w);CHKERRQ(ierr);
2625     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2626     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2627     ierr = VecDestroy(&w);CHKERRQ(ierr);
2628     ierr = VecConjugate(z);CHKERRQ(ierr);
2629     if (v2 != v3) {
2630       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2631     } else {
2632       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2633     }
2634     ierr = VecDestroy(&z);CHKERRQ(ierr);
2635   }
2636   ierr = VecLockPop(v1);CHKERRQ(ierr);
2637   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2638   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2639   PetscFunctionReturn(0);
2640 }
2641 
2642 /*@
2643    MatMultConstrained - The inner multiplication routine for a
2644    constrained matrix P^T A P.
2645 
2646    Neighbor-wise Collective on Mat and Vec
2647 
2648    Input Parameters:
2649 +  mat - the matrix
2650 -  x   - the vector to be multilplied
2651 
2652    Output Parameters:
2653 .  y - the result
2654 
2655    Notes:
2656    The vectors x and y cannot be the same.  I.e., one cannot
2657    call MatMult(A,y,y).
2658 
2659    Level: beginner
2660 
2661 .keywords: matrix, multiply, matrix-vector product, constraint
2662 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2663 @*/
2664 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2665 {
2666   PetscErrorCode ierr;
2667 
2668   PetscFunctionBegin;
2669   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2670   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2671   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2672   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2673   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2674   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2675   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2676   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2677   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2678 
2679   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2680   ierr = VecLockPush(x);CHKERRQ(ierr);
2681   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2682   ierr = VecLockPop(x);CHKERRQ(ierr);
2683   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2684   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2685   PetscFunctionReturn(0);
2686 }
2687 
2688 /*@
2689    MatMultTransposeConstrained - The inner multiplication routine for a
2690    constrained matrix P^T A^T P.
2691 
2692    Neighbor-wise Collective on Mat and Vec
2693 
2694    Input Parameters:
2695 +  mat - the matrix
2696 -  x   - the vector to be multilplied
2697 
2698    Output Parameters:
2699 .  y - the result
2700 
2701    Notes:
2702    The vectors x and y cannot be the same.  I.e., one cannot
2703    call MatMult(A,y,y).
2704 
2705    Level: beginner
2706 
2707 .keywords: matrix, multiply, matrix-vector product, constraint
2708 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2709 @*/
2710 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2711 {
2712   PetscErrorCode ierr;
2713 
2714   PetscFunctionBegin;
2715   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2716   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2717   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2718   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2719   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2720   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2721   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2722   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2723 
2724   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2725   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2726   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2727   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2728   PetscFunctionReturn(0);
2729 }
2730 
2731 /*@C
2732    MatGetFactorType - gets the type of factorization it is
2733 
2734    Not Collective
2735 
2736    Input Parameters:
2737 .  mat - the matrix
2738 
2739    Output Parameters:
2740 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2741 
2742    Level: intermediate
2743 
2744 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2745 @*/
2746 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2747 {
2748   PetscFunctionBegin;
2749   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2750   PetscValidType(mat,1);
2751   PetscValidPointer(t,2);
2752   *t = mat->factortype;
2753   PetscFunctionReturn(0);
2754 }
2755 
2756 /*@C
2757    MatSetFactorType - sets the type of factorization it is
2758 
2759    Logically Collective on Mat
2760 
2761    Input Parameters:
2762 +  mat - the matrix
2763 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2764 
2765    Level: intermediate
2766 
2767 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2768 @*/
2769 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2770 {
2771   PetscFunctionBegin;
2772   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2773   PetscValidType(mat,1);
2774   mat->factortype = t;
2775   PetscFunctionReturn(0);
2776 }
2777 
2778 /* ------------------------------------------------------------*/
2779 /*@C
2780    MatGetInfo - Returns information about matrix storage (number of
2781    nonzeros, memory, etc.).
2782 
2783    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2784 
2785    Input Parameters:
2786 .  mat - the matrix
2787 
2788    Output Parameters:
2789 +  flag - flag indicating the type of parameters to be returned
2790    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2791    MAT_GLOBAL_SUM - sum over all processors)
2792 -  info - matrix information context
2793 
2794    Notes:
2795    The MatInfo context contains a variety of matrix data, including
2796    number of nonzeros allocated and used, number of mallocs during
2797    matrix assembly, etc.  Additional information for factored matrices
2798    is provided (such as the fill ratio, number of mallocs during
2799    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2800    when using the runtime options
2801 $       -info -mat_view ::ascii_info
2802 
2803    Example for C/C++ Users:
2804    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2805    data within the MatInfo context.  For example,
2806 .vb
2807       MatInfo info;
2808       Mat     A;
2809       double  mal, nz_a, nz_u;
2810 
2811       MatGetInfo(A,MAT_LOCAL,&info);
2812       mal  = info.mallocs;
2813       nz_a = info.nz_allocated;
2814 .ve
2815 
2816    Example for Fortran Users:
2817    Fortran users should declare info as a double precision
2818    array of dimension MAT_INFO_SIZE, and then extract the parameters
2819    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2820    a complete list of parameter names.
2821 .vb
2822       double  precision info(MAT_INFO_SIZE)
2823       double  precision mal, nz_a
2824       Mat     A
2825       integer ierr
2826 
2827       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2828       mal = info(MAT_INFO_MALLOCS)
2829       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2830 .ve
2831 
2832     Level: intermediate
2833 
2834     Concepts: matrices^getting information on
2835 
2836     Developer Note: fortran interface is not autogenerated as the f90
2837     interface defintion cannot be generated correctly [due to MatInfo]
2838 
2839 .seealso: MatStashGetInfo()
2840 
2841 @*/
2842 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2843 {
2844   PetscErrorCode ierr;
2845 
2846   PetscFunctionBegin;
2847   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2848   PetscValidType(mat,1);
2849   PetscValidPointer(info,3);
2850   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2851   MatCheckPreallocated(mat,1);
2852   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2853   PetscFunctionReturn(0);
2854 }
2855 
2856 /*
2857    This is used by external packages where it is not easy to get the info from the actual
2858    matrix factorization.
2859 */
2860 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2861 {
2862   PetscErrorCode ierr;
2863 
2864   PetscFunctionBegin;
2865   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2866   PetscFunctionReturn(0);
2867 }
2868 
2869 /* ----------------------------------------------------------*/
2870 
2871 /*@C
2872    MatLUFactor - Performs in-place LU factorization of matrix.
2873 
2874    Collective on Mat
2875 
2876    Input Parameters:
2877 +  mat - the matrix
2878 .  row - row permutation
2879 .  col - column permutation
2880 -  info - options for factorization, includes
2881 $          fill - expected fill as ratio of original fill.
2882 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2883 $                   Run with the option -info to determine an optimal value to use
2884 
2885    Notes:
2886    Most users should employ the simplified KSP interface for linear solvers
2887    instead of working directly with matrix algebra routines such as this.
2888    See, e.g., KSPCreate().
2889 
2890    This changes the state of the matrix to a factored matrix; it cannot be used
2891    for example with MatSetValues() unless one first calls MatSetUnfactored().
2892 
2893    Level: developer
2894 
2895    Concepts: matrices^LU factorization
2896 
2897 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2898           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2899 
2900     Developer Note: fortran interface is not autogenerated as the f90
2901     interface defintion cannot be generated correctly [due to MatFactorInfo]
2902 
2903 @*/
2904 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2905 {
2906   PetscErrorCode ierr;
2907   MatFactorInfo  tinfo;
2908 
2909   PetscFunctionBegin;
2910   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2911   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2912   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2913   if (info) PetscValidPointer(info,4);
2914   PetscValidType(mat,1);
2915   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2916   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2917   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2918   MatCheckPreallocated(mat,1);
2919   if (!info) {
2920     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2921     info = &tinfo;
2922   }
2923 
2924   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2925   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2926   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2927   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2928   PetscFunctionReturn(0);
2929 }
2930 
2931 /*@C
2932    MatILUFactor - Performs in-place ILU factorization of matrix.
2933 
2934    Collective on Mat
2935 
2936    Input Parameters:
2937 +  mat - the matrix
2938 .  row - row permutation
2939 .  col - column permutation
2940 -  info - structure containing
2941 $      levels - number of levels of fill.
2942 $      expected fill - as ratio of original fill.
2943 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2944                 missing diagonal entries)
2945 
2946    Notes:
2947    Probably really in-place only when level of fill is zero, otherwise allocates
2948    new space to store factored matrix and deletes previous memory.
2949 
2950    Most users should employ the simplified KSP interface for linear solvers
2951    instead of working directly with matrix algebra routines such as this.
2952    See, e.g., KSPCreate().
2953 
2954    Level: developer
2955 
2956    Concepts: matrices^ILU factorization
2957 
2958 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2959 
2960     Developer Note: fortran interface is not autogenerated as the f90
2961     interface defintion cannot be generated correctly [due to MatFactorInfo]
2962 
2963 @*/
2964 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2965 {
2966   PetscErrorCode ierr;
2967 
2968   PetscFunctionBegin;
2969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2970   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2971   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2972   PetscValidPointer(info,4);
2973   PetscValidType(mat,1);
2974   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2975   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2976   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2977   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2978   MatCheckPreallocated(mat,1);
2979 
2980   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2981   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2982   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2983   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2984   PetscFunctionReturn(0);
2985 }
2986 
2987 /*@C
2988    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2989    Call this routine before calling MatLUFactorNumeric().
2990 
2991    Collective on Mat
2992 
2993    Input Parameters:
2994 +  fact - the factor matrix obtained with MatGetFactor()
2995 .  mat - the matrix
2996 .  row, col - row and column permutations
2997 -  info - options for factorization, includes
2998 $          fill - expected fill as ratio of original fill.
2999 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3000 $                   Run with the option -info to determine an optimal value to use
3001 
3002 
3003    Notes:
3004     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3005 
3006    Most users should employ the simplified KSP interface for linear solvers
3007    instead of working directly with matrix algebra routines such as this.
3008    See, e.g., KSPCreate().
3009 
3010    Level: developer
3011 
3012    Concepts: matrices^LU symbolic factorization
3013 
3014 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3015 
3016     Developer Note: fortran interface is not autogenerated as the f90
3017     interface defintion cannot be generated correctly [due to MatFactorInfo]
3018 
3019 @*/
3020 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3021 {
3022   PetscErrorCode ierr;
3023 
3024   PetscFunctionBegin;
3025   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3026   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3027   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3028   if (info) PetscValidPointer(info,4);
3029   PetscValidType(mat,1);
3030   PetscValidPointer(fact,5);
3031   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3032   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3033   if (!(fact)->ops->lufactorsymbolic) {
3034     MatSolverType spackage;
3035     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3036     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3037   }
3038   MatCheckPreallocated(mat,2);
3039 
3040   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3041   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3042   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3043   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3044   PetscFunctionReturn(0);
3045 }
3046 
3047 /*@C
3048    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3049    Call this routine after first calling MatLUFactorSymbolic().
3050 
3051    Collective on Mat
3052 
3053    Input Parameters:
3054 +  fact - the factor matrix obtained with MatGetFactor()
3055 .  mat - the matrix
3056 -  info - options for factorization
3057 
3058    Notes:
3059    See MatLUFactor() for in-place factorization.  See
3060    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3061 
3062    Most users should employ the simplified KSP interface for linear solvers
3063    instead of working directly with matrix algebra routines such as this.
3064    See, e.g., KSPCreate().
3065 
3066    Level: developer
3067 
3068    Concepts: matrices^LU numeric factorization
3069 
3070 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3071 
3072     Developer Note: fortran interface is not autogenerated as the f90
3073     interface defintion cannot be generated correctly [due to MatFactorInfo]
3074 
3075 @*/
3076 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3077 {
3078   PetscErrorCode ierr;
3079 
3080   PetscFunctionBegin;
3081   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3082   PetscValidType(mat,1);
3083   PetscValidPointer(fact,2);
3084   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3085   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3086   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3087 
3088   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3089   MatCheckPreallocated(mat,2);
3090   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3091   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3092   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3093   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3094   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3095   PetscFunctionReturn(0);
3096 }
3097 
3098 /*@C
3099    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3100    symmetric matrix.
3101 
3102    Collective on Mat
3103 
3104    Input Parameters:
3105 +  mat - the matrix
3106 .  perm - row and column permutations
3107 -  f - expected fill as ratio of original fill
3108 
3109    Notes:
3110    See MatLUFactor() for the nonsymmetric case.  See also
3111    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3112 
3113    Most users should employ the simplified KSP interface for linear solvers
3114    instead of working directly with matrix algebra routines such as this.
3115    See, e.g., KSPCreate().
3116 
3117    Level: developer
3118 
3119    Concepts: matrices^Cholesky factorization
3120 
3121 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3122           MatGetOrdering()
3123 
3124     Developer Note: fortran interface is not autogenerated as the f90
3125     interface defintion cannot be generated correctly [due to MatFactorInfo]
3126 
3127 @*/
3128 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3129 {
3130   PetscErrorCode ierr;
3131 
3132   PetscFunctionBegin;
3133   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3134   PetscValidType(mat,1);
3135   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3136   if (info) PetscValidPointer(info,3);
3137   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3138   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3139   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3140   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3141   MatCheckPreallocated(mat,1);
3142 
3143   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3144   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3145   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3146   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3147   PetscFunctionReturn(0);
3148 }
3149 
3150 /*@C
3151    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3152    of a symmetric matrix.
3153 
3154    Collective on Mat
3155 
3156    Input Parameters:
3157 +  fact - the factor matrix obtained with MatGetFactor()
3158 .  mat - the matrix
3159 .  perm - row and column permutations
3160 -  info - options for factorization, includes
3161 $          fill - expected fill as ratio of original fill.
3162 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3163 $                   Run with the option -info to determine an optimal value to use
3164 
3165    Notes:
3166    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3167    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3168 
3169    Most users should employ the simplified KSP interface for linear solvers
3170    instead of working directly with matrix algebra routines such as this.
3171    See, e.g., KSPCreate().
3172 
3173    Level: developer
3174 
3175    Concepts: matrices^Cholesky symbolic factorization
3176 
3177 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3178           MatGetOrdering()
3179 
3180     Developer Note: fortran interface is not autogenerated as the f90
3181     interface defintion cannot be generated correctly [due to MatFactorInfo]
3182 
3183 @*/
3184 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3185 {
3186   PetscErrorCode ierr;
3187 
3188   PetscFunctionBegin;
3189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3190   PetscValidType(mat,1);
3191   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3192   if (info) PetscValidPointer(info,3);
3193   PetscValidPointer(fact,4);
3194   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3195   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3196   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3197   if (!(fact)->ops->choleskyfactorsymbolic) {
3198     MatSolverType spackage;
3199     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3200     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3201   }
3202   MatCheckPreallocated(mat,2);
3203 
3204   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3205   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3206   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3207   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3208   PetscFunctionReturn(0);
3209 }
3210 
3211 /*@C
3212    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3213    of a symmetric matrix. Call this routine after first calling
3214    MatCholeskyFactorSymbolic().
3215 
3216    Collective on Mat
3217 
3218    Input Parameters:
3219 +  fact - the factor matrix obtained with MatGetFactor()
3220 .  mat - the initial matrix
3221 .  info - options for factorization
3222 -  fact - the symbolic factor of mat
3223 
3224 
3225    Notes:
3226    Most users should employ the simplified KSP interface for linear solvers
3227    instead of working directly with matrix algebra routines such as this.
3228    See, e.g., KSPCreate().
3229 
3230    Level: developer
3231 
3232    Concepts: matrices^Cholesky numeric factorization
3233 
3234 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3235 
3236     Developer Note: fortran interface is not autogenerated as the f90
3237     interface defintion cannot be generated correctly [due to MatFactorInfo]
3238 
3239 @*/
3240 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3241 {
3242   PetscErrorCode ierr;
3243 
3244   PetscFunctionBegin;
3245   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3246   PetscValidType(mat,1);
3247   PetscValidPointer(fact,2);
3248   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3249   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3250   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3251   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3252   MatCheckPreallocated(mat,2);
3253 
3254   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3255   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3256   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3257   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3258   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3259   PetscFunctionReturn(0);
3260 }
3261 
3262 /* ----------------------------------------------------------------*/
3263 /*@
3264    MatSolve - Solves A x = b, given a factored matrix.
3265 
3266    Neighbor-wise Collective on Mat and Vec
3267 
3268    Input Parameters:
3269 +  mat - the factored matrix
3270 -  b - the right-hand-side vector
3271 
3272    Output Parameter:
3273 .  x - the result vector
3274 
3275    Notes:
3276    The vectors b and x cannot be the same.  I.e., one cannot
3277    call MatSolve(A,x,x).
3278 
3279    Notes:
3280    Most users should employ the simplified KSP interface for linear solvers
3281    instead of working directly with matrix algebra routines such as this.
3282    See, e.g., KSPCreate().
3283 
3284    Level: developer
3285 
3286    Concepts: matrices^triangular solves
3287 
3288 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3289 @*/
3290 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3291 {
3292   PetscErrorCode ierr;
3293 
3294   PetscFunctionBegin;
3295   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3296   PetscValidType(mat,1);
3297   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3298   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3299   PetscCheckSameComm(mat,1,b,2);
3300   PetscCheckSameComm(mat,1,x,3);
3301   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3302   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3303   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3304   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3305   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3306   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3307   MatCheckPreallocated(mat,1);
3308 
3309   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3310   if (mat->factorerrortype) {
3311     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3312     ierr = VecSetInf(x);CHKERRQ(ierr);
3313   } else {
3314     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3315     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3316   }
3317   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3318   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3319   PetscFunctionReturn(0);
3320 }
3321 
3322 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3323 {
3324   PetscErrorCode ierr;
3325   Vec            b,x;
3326   PetscInt       m,N,i;
3327   PetscScalar    *bb,*xx;
3328   PetscBool      flg;
3329 
3330   PetscFunctionBegin;
3331   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3332   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3333   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3334   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3335 
3336   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3337   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3338   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3339   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3340   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3341   for (i=0; i<N; i++) {
3342     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3343     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3344     if (trans) {
3345       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3346     } else {
3347       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3348     }
3349     ierr = VecResetArray(x);CHKERRQ(ierr);
3350     ierr = VecResetArray(b);CHKERRQ(ierr);
3351   }
3352   ierr = VecDestroy(&b);CHKERRQ(ierr);
3353   ierr = VecDestroy(&x);CHKERRQ(ierr);
3354   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3355   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3356   PetscFunctionReturn(0);
3357 }
3358 
3359 /*@
3360    MatMatSolve - Solves A X = B, given a factored matrix.
3361 
3362    Neighbor-wise Collective on Mat
3363 
3364    Input Parameters:
3365 +  A - the factored matrix
3366 -  B - the right-hand-side matrix  (dense matrix)
3367 
3368    Output Parameter:
3369 .  X - the result matrix (dense matrix)
3370 
3371    Notes:
3372    The matrices b and x cannot be the same.  I.e., one cannot
3373    call MatMatSolve(A,x,x).
3374 
3375    Notes:
3376    Most users should usually employ the simplified KSP interface for linear solvers
3377    instead of working directly with matrix algebra routines such as this.
3378    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3379    at a time.
3380 
3381    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3382    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3383 
3384    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3385 
3386    Level: developer
3387 
3388    Concepts: matrices^triangular solves
3389 
3390 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3391 @*/
3392 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3393 {
3394   PetscErrorCode ierr;
3395 
3396   PetscFunctionBegin;
3397   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3398   PetscValidType(A,1);
3399   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3400   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3401   PetscCheckSameComm(A,1,B,2);
3402   PetscCheckSameComm(A,1,X,3);
3403   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3404   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3405   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3406   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3407   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3408   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3409   MatCheckPreallocated(A,1);
3410 
3411   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3412   if (!A->ops->matsolve) {
3413     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3414     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3415   } else {
3416     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3417   }
3418   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3419   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3420   PetscFunctionReturn(0);
3421 }
3422 
3423 /*@
3424    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3425 
3426    Neighbor-wise Collective on Mat
3427 
3428    Input Parameters:
3429 +  A - the factored matrix
3430 -  B - the right-hand-side matrix  (dense matrix)
3431 
3432    Output Parameter:
3433 .  X - the result matrix (dense matrix)
3434 
3435    Notes:
3436    The matrices B and X cannot be the same.  I.e., one cannot
3437    call MatMatSolveTranspose(A,X,X).
3438 
3439    Notes:
3440    Most users should usually employ the simplified KSP interface for linear solvers
3441    instead of working directly with matrix algebra routines such as this.
3442    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3443    at a time.
3444 
3445    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3446 
3447    Level: developer
3448 
3449    Concepts: matrices^triangular solves
3450 
3451 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3452 @*/
3453 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3454 {
3455   PetscErrorCode ierr;
3456 
3457   PetscFunctionBegin;
3458   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3459   PetscValidType(A,1);
3460   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3461   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3462   PetscCheckSameComm(A,1,B,2);
3463   PetscCheckSameComm(A,1,X,3);
3464   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3465   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3466   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3467   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3468   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3469   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3470   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3471   MatCheckPreallocated(A,1);
3472 
3473   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3474   if (!A->ops->matsolvetranspose) {
3475     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3476     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3477   } else {
3478     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3479   }
3480   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3481   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3482   PetscFunctionReturn(0);
3483 }
3484 
3485 /*@
3486    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3487 
3488    Neighbor-wise Collective on Mat
3489 
3490    Input Parameters:
3491 +  A - the factored matrix
3492 -  Bt - the transpose of right-hand-side matrix
3493 
3494    Output Parameter:
3495 .  X - the result matrix (dense matrix)
3496 
3497    Notes:
3498    Most users should usually employ the simplified KSP interface for linear solvers
3499    instead of working directly with matrix algebra routines such as this.
3500    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3501    at a time.
3502 
3503    For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve().
3504 
3505    Level: developer
3506 
3507    Concepts: matrices^triangular solves
3508 
3509 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3510 @*/
3511 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3512 {
3513   PetscErrorCode ierr;
3514 
3515   PetscFunctionBegin;
3516   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3517   PetscValidType(A,1);
3518   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3519   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3520   PetscCheckSameComm(A,1,Bt,2);
3521   PetscCheckSameComm(A,1,X,3);
3522 
3523   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3524   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3525   if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3526   if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3527   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3528   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3529   MatCheckPreallocated(A,1);
3530 
3531   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3532   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3533   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3534   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3535   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3536   PetscFunctionReturn(0);
3537 }
3538 
3539 /*@
3540    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3541                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3542 
3543    Neighbor-wise Collective on Mat and Vec
3544 
3545    Input Parameters:
3546 +  mat - the factored matrix
3547 -  b - the right-hand-side vector
3548 
3549    Output Parameter:
3550 .  x - the result vector
3551 
3552    Notes:
3553    MatSolve() should be used for most applications, as it performs
3554    a forward solve followed by a backward solve.
3555 
3556    The vectors b and x cannot be the same,  i.e., one cannot
3557    call MatForwardSolve(A,x,x).
3558 
3559    For matrix in seqsbaij format with block size larger than 1,
3560    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3561    MatForwardSolve() solves U^T*D y = b, and
3562    MatBackwardSolve() solves U x = y.
3563    Thus they do not provide a symmetric preconditioner.
3564 
3565    Most users should employ the simplified KSP interface for linear solvers
3566    instead of working directly with matrix algebra routines such as this.
3567    See, e.g., KSPCreate().
3568 
3569    Level: developer
3570 
3571    Concepts: matrices^forward solves
3572 
3573 .seealso: MatSolve(), MatBackwardSolve()
3574 @*/
3575 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3576 {
3577   PetscErrorCode ierr;
3578 
3579   PetscFunctionBegin;
3580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3581   PetscValidType(mat,1);
3582   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3583   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3584   PetscCheckSameComm(mat,1,b,2);
3585   PetscCheckSameComm(mat,1,x,3);
3586   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3587   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3588   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3589   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3590   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3591   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3592   MatCheckPreallocated(mat,1);
3593 
3594   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3595   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3596   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3597   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3598   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3599   PetscFunctionReturn(0);
3600 }
3601 
3602 /*@
3603    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3604                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3605 
3606    Neighbor-wise Collective on Mat and Vec
3607 
3608    Input Parameters:
3609 +  mat - the factored matrix
3610 -  b - the right-hand-side vector
3611 
3612    Output Parameter:
3613 .  x - the result vector
3614 
3615    Notes:
3616    MatSolve() should be used for most applications, as it performs
3617    a forward solve followed by a backward solve.
3618 
3619    The vectors b and x cannot be the same.  I.e., one cannot
3620    call MatBackwardSolve(A,x,x).
3621 
3622    For matrix in seqsbaij format with block size larger than 1,
3623    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3624    MatForwardSolve() solves U^T*D y = b, and
3625    MatBackwardSolve() solves U x = y.
3626    Thus they do not provide a symmetric preconditioner.
3627 
3628    Most users should employ the simplified KSP interface for linear solvers
3629    instead of working directly with matrix algebra routines such as this.
3630    See, e.g., KSPCreate().
3631 
3632    Level: developer
3633 
3634    Concepts: matrices^backward solves
3635 
3636 .seealso: MatSolve(), MatForwardSolve()
3637 @*/
3638 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3639 {
3640   PetscErrorCode ierr;
3641 
3642   PetscFunctionBegin;
3643   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3644   PetscValidType(mat,1);
3645   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3646   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3647   PetscCheckSameComm(mat,1,b,2);
3648   PetscCheckSameComm(mat,1,x,3);
3649   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3650   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3651   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3652   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3653   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3654   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3655   MatCheckPreallocated(mat,1);
3656 
3657   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3658   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3659   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3660   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3661   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3662   PetscFunctionReturn(0);
3663 }
3664 
3665 /*@
3666    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3667 
3668    Neighbor-wise Collective on Mat and Vec
3669 
3670    Input Parameters:
3671 +  mat - the factored matrix
3672 .  b - the right-hand-side vector
3673 -  y - the vector to be added to
3674 
3675    Output Parameter:
3676 .  x - the result vector
3677 
3678    Notes:
3679    The vectors b and x cannot be the same.  I.e., one cannot
3680    call MatSolveAdd(A,x,y,x).
3681 
3682    Most users should employ the simplified KSP interface for linear solvers
3683    instead of working directly with matrix algebra routines such as this.
3684    See, e.g., KSPCreate().
3685 
3686    Level: developer
3687 
3688    Concepts: matrices^triangular solves
3689 
3690 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3691 @*/
3692 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3693 {
3694   PetscScalar    one = 1.0;
3695   Vec            tmp;
3696   PetscErrorCode ierr;
3697 
3698   PetscFunctionBegin;
3699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3700   PetscValidType(mat,1);
3701   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3702   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3703   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3704   PetscCheckSameComm(mat,1,b,2);
3705   PetscCheckSameComm(mat,1,y,2);
3706   PetscCheckSameComm(mat,1,x,3);
3707   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3708   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3709   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3710   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3711   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3712   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3713   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3714   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3715   MatCheckPreallocated(mat,1);
3716 
3717   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3718   if (mat->ops->solveadd) {
3719     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3720   } else {
3721     /* do the solve then the add manually */
3722     if (x != y) {
3723       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3724       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3725     } else {
3726       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3727       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3728       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3729       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3730       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3731       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3732     }
3733   }
3734   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3735   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3736   PetscFunctionReturn(0);
3737 }
3738 
3739 /*@
3740    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3741 
3742    Neighbor-wise Collective on Mat and Vec
3743 
3744    Input Parameters:
3745 +  mat - the factored matrix
3746 -  b - the right-hand-side vector
3747 
3748    Output Parameter:
3749 .  x - the result vector
3750 
3751    Notes:
3752    The vectors b and x cannot be the same.  I.e., one cannot
3753    call MatSolveTranspose(A,x,x).
3754 
3755    Most users should employ the simplified KSP interface for linear solvers
3756    instead of working directly with matrix algebra routines such as this.
3757    See, e.g., KSPCreate().
3758 
3759    Level: developer
3760 
3761    Concepts: matrices^triangular solves
3762 
3763 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3764 @*/
3765 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3766 {
3767   PetscErrorCode ierr;
3768 
3769   PetscFunctionBegin;
3770   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3771   PetscValidType(mat,1);
3772   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3773   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3774   PetscCheckSameComm(mat,1,b,2);
3775   PetscCheckSameComm(mat,1,x,3);
3776   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3777   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3778   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3779   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3780   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3781   MatCheckPreallocated(mat,1);
3782   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3783   if (mat->factorerrortype) {
3784     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3785     ierr = VecSetInf(x);CHKERRQ(ierr);
3786   } else {
3787     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3788     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3789   }
3790   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3791   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3792   PetscFunctionReturn(0);
3793 }
3794 
3795 /*@
3796    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3797                       factored matrix.
3798 
3799    Neighbor-wise Collective on Mat and Vec
3800 
3801    Input Parameters:
3802 +  mat - the factored matrix
3803 .  b - the right-hand-side vector
3804 -  y - the vector to be added to
3805 
3806    Output Parameter:
3807 .  x - the result vector
3808 
3809    Notes:
3810    The vectors b and x cannot be the same.  I.e., one cannot
3811    call MatSolveTransposeAdd(A,x,y,x).
3812 
3813    Most users should employ the simplified KSP interface for linear solvers
3814    instead of working directly with matrix algebra routines such as this.
3815    See, e.g., KSPCreate().
3816 
3817    Level: developer
3818 
3819    Concepts: matrices^triangular solves
3820 
3821 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3822 @*/
3823 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3824 {
3825   PetscScalar    one = 1.0;
3826   PetscErrorCode ierr;
3827   Vec            tmp;
3828 
3829   PetscFunctionBegin;
3830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3831   PetscValidType(mat,1);
3832   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3833   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3834   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3835   PetscCheckSameComm(mat,1,b,2);
3836   PetscCheckSameComm(mat,1,y,3);
3837   PetscCheckSameComm(mat,1,x,4);
3838   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3839   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3840   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3841   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3842   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3843   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3844   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3845   MatCheckPreallocated(mat,1);
3846 
3847   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3848   if (mat->ops->solvetransposeadd) {
3849     if (mat->factorerrortype) {
3850       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3851       ierr = VecSetInf(x);CHKERRQ(ierr);
3852     } else {
3853       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3854     }
3855   } else {
3856     /* do the solve then the add manually */
3857     if (x != y) {
3858       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3859       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3860     } else {
3861       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3862       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3863       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3864       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3865       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3866       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3867     }
3868   }
3869   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3870   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3871   PetscFunctionReturn(0);
3872 }
3873 /* ----------------------------------------------------------------*/
3874 
3875 /*@
3876    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3877 
3878    Neighbor-wise Collective on Mat and Vec
3879 
3880    Input Parameters:
3881 +  mat - the matrix
3882 .  b - the right hand side
3883 .  omega - the relaxation factor
3884 .  flag - flag indicating the type of SOR (see below)
3885 .  shift -  diagonal shift
3886 .  its - the number of iterations
3887 -  lits - the number of local iterations
3888 
3889    Output Parameters:
3890 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3891 
3892    SOR Flags:
3893 .     SOR_FORWARD_SWEEP - forward SOR
3894 .     SOR_BACKWARD_SWEEP - backward SOR
3895 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3896 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3897 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3898 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3899 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3900          upper/lower triangular part of matrix to
3901          vector (with omega)
3902 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3903 
3904    Notes:
3905    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3906    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3907    on each processor.
3908 
3909    Application programmers will not generally use MatSOR() directly,
3910    but instead will employ the KSP/PC interface.
3911 
3912    Notes:
3913     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3914 
3915    Notes for Advanced Users:
3916    The flags are implemented as bitwise inclusive or operations.
3917    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3918    to specify a zero initial guess for SSOR.
3919 
3920    Most users should employ the simplified KSP interface for linear solvers
3921    instead of working directly with matrix algebra routines such as this.
3922    See, e.g., KSPCreate().
3923 
3924    Vectors x and b CANNOT be the same
3925 
3926    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3927 
3928    Level: developer
3929 
3930    Concepts: matrices^relaxation
3931    Concepts: matrices^SOR
3932    Concepts: matrices^Gauss-Seidel
3933 
3934 @*/
3935 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3936 {
3937   PetscErrorCode ierr;
3938 
3939   PetscFunctionBegin;
3940   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3941   PetscValidType(mat,1);
3942   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3943   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3944   PetscCheckSameComm(mat,1,b,2);
3945   PetscCheckSameComm(mat,1,x,8);
3946   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3947   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3948   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3949   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3950   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3951   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3952   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3953   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3954   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3955 
3956   MatCheckPreallocated(mat,1);
3957   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3958   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3959   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3960   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3961   PetscFunctionReturn(0);
3962 }
3963 
3964 /*
3965       Default matrix copy routine.
3966 */
3967 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3968 {
3969   PetscErrorCode    ierr;
3970   PetscInt          i,rstart = 0,rend = 0,nz;
3971   const PetscInt    *cwork;
3972   const PetscScalar *vwork;
3973 
3974   PetscFunctionBegin;
3975   if (B->assembled) {
3976     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3977   }
3978   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3979   for (i=rstart; i<rend; i++) {
3980     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3981     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3982     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3983   }
3984   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3985   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3986   PetscFunctionReturn(0);
3987 }
3988 
3989 /*@
3990    MatCopy - Copys a matrix to another matrix.
3991 
3992    Collective on Mat
3993 
3994    Input Parameters:
3995 +  A - the matrix
3996 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3997 
3998    Output Parameter:
3999 .  B - where the copy is put
4000 
4001    Notes:
4002    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4003    same nonzero pattern or the routine will crash.
4004 
4005    MatCopy() copies the matrix entries of a matrix to another existing
4006    matrix (after first zeroing the second matrix).  A related routine is
4007    MatConvert(), which first creates a new matrix and then copies the data.
4008 
4009    Level: intermediate
4010 
4011    Concepts: matrices^copying
4012 
4013 .seealso: MatConvert(), MatDuplicate()
4014 
4015 @*/
4016 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4017 {
4018   PetscErrorCode ierr;
4019   PetscInt       i;
4020 
4021   PetscFunctionBegin;
4022   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4023   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4024   PetscValidType(A,1);
4025   PetscValidType(B,2);
4026   PetscCheckSameComm(A,1,B,2);
4027   MatCheckPreallocated(B,2);
4028   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4029   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4030   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4031   MatCheckPreallocated(A,1);
4032   if (A == B) PetscFunctionReturn(0);
4033 
4034   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4035   if (A->ops->copy) {
4036     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4037   } else { /* generic conversion */
4038     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4039   }
4040 
4041   B->stencil.dim = A->stencil.dim;
4042   B->stencil.noc = A->stencil.noc;
4043   for (i=0; i<=A->stencil.dim; i++) {
4044     B->stencil.dims[i]   = A->stencil.dims[i];
4045     B->stencil.starts[i] = A->stencil.starts[i];
4046   }
4047 
4048   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4049   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4050   PetscFunctionReturn(0);
4051 }
4052 
4053 /*@C
4054    MatConvert - Converts a matrix to another matrix, either of the same
4055    or different type.
4056 
4057    Collective on Mat
4058 
4059    Input Parameters:
4060 +  mat - the matrix
4061 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4062    same type as the original matrix.
4063 -  reuse - denotes if the destination matrix is to be created or reused.
4064    Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
4065    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).
4066 
4067    Output Parameter:
4068 .  M - pointer to place new matrix
4069 
4070    Notes:
4071    MatConvert() first creates a new matrix and then copies the data from
4072    the first matrix.  A related routine is MatCopy(), which copies the matrix
4073    entries of one matrix to another already existing matrix context.
4074 
4075    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4076    the MPI communicator of the generated matrix is always the same as the communicator
4077    of the input matrix.
4078 
4079    Level: intermediate
4080 
4081    Concepts: matrices^converting between storage formats
4082 
4083 .seealso: MatCopy(), MatDuplicate()
4084 @*/
4085 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4086 {
4087   PetscErrorCode ierr;
4088   PetscBool      sametype,issame,flg;
4089   char           convname[256],mtype[256];
4090   Mat            B;
4091 
4092   PetscFunctionBegin;
4093   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4094   PetscValidType(mat,1);
4095   PetscValidPointer(M,3);
4096   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4097   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4098   MatCheckPreallocated(mat,1);
4099 
4100   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4101   if (flg) {
4102     newtype = mtype;
4103   }
4104   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4105   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4106   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4107   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4108 
4109   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4110 
4111   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4112     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4113   } else {
4114     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4115     const char     *prefix[3] = {"seq","mpi",""};
4116     PetscInt       i;
4117     /*
4118        Order of precedence:
4119        1) See if a specialized converter is known to the current matrix.
4120        2) See if a specialized converter is known to the desired matrix class.
4121        3) See if a good general converter is registered for the desired class
4122           (as of 6/27/03 only MATMPIADJ falls into this category).
4123        4) See if a good general converter is known for the current matrix.
4124        5) Use a really basic converter.
4125     */
4126 
4127     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4128     for (i=0; i<3; i++) {
4129       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4130       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4131       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4132       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4133       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4134       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4135       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4136       if (conv) goto foundconv;
4137     }
4138 
4139     /* 2)  See if a specialized converter is known to the desired matrix class. */
4140     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4141     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4142     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4143     for (i=0; i<3; i++) {
4144       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4145       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4146       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4147       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4148       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4149       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4150       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4151       if (conv) {
4152         ierr = MatDestroy(&B);CHKERRQ(ierr);
4153         goto foundconv;
4154       }
4155     }
4156 
4157     /* 3) See if a good general converter is registered for the desired class */
4158     conv = B->ops->convertfrom;
4159     ierr = MatDestroy(&B);CHKERRQ(ierr);
4160     if (conv) goto foundconv;
4161 
4162     /* 4) See if a good general converter is known for the current matrix */
4163     if (mat->ops->convert) {
4164       conv = mat->ops->convert;
4165     }
4166     if (conv) goto foundconv;
4167 
4168     /* 5) Use a really basic converter. */
4169     conv = MatConvert_Basic;
4170 
4171 foundconv:
4172     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4173     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4174     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4175       /* the block sizes must be same if the mappings are copied over */
4176       (*M)->rmap->bs = mat->rmap->bs;
4177       (*M)->cmap->bs = mat->cmap->bs;
4178       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4179       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4180       (*M)->rmap->mapping = mat->rmap->mapping;
4181       (*M)->cmap->mapping = mat->cmap->mapping;
4182     }
4183     (*M)->stencil.dim = mat->stencil.dim;
4184     (*M)->stencil.noc = mat->stencil.noc;
4185     for (i=0; i<=mat->stencil.dim; i++) {
4186       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4187       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4188     }
4189     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4190   }
4191   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4192 
4193   /* Copy Mat options */
4194   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4195   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4196   PetscFunctionReturn(0);
4197 }
4198 
4199 /*@C
4200    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4201 
4202    Not Collective
4203 
4204    Input Parameter:
4205 .  mat - the matrix, must be a factored matrix
4206 
4207    Output Parameter:
4208 .   type - the string name of the package (do not free this string)
4209 
4210    Notes:
4211       In Fortran you pass in a empty string and the package name will be copied into it.
4212     (Make sure the string is long enough)
4213 
4214    Level: intermediate
4215 
4216 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4217 @*/
4218 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4219 {
4220   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4221 
4222   PetscFunctionBegin;
4223   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4224   PetscValidType(mat,1);
4225   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4226   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4227   if (!conv) {
4228     *type = MATSOLVERPETSC;
4229   } else {
4230     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4231   }
4232   PetscFunctionReturn(0);
4233 }
4234 
4235 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4236 struct _MatSolverTypeForSpecifcType {
4237   MatType                        mtype;
4238   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4239   MatSolverTypeForSpecifcType next;
4240 };
4241 
4242 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4243 struct _MatSolverTypeHolder {
4244   char                           *name;
4245   MatSolverTypeForSpecifcType handlers;
4246   MatSolverTypeHolder         next;
4247 };
4248 
4249 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4250 
4251 /*@C
4252    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4253 
4254    Input Parameters:
4255 +    package - name of the package, for example petsc or superlu
4256 .    mtype - the matrix type that works with this package
4257 .    ftype - the type of factorization supported by the package
4258 -    getfactor - routine that will create the factored matrix ready to be used
4259 
4260     Level: intermediate
4261 
4262 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4263 @*/
4264 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4265 {
4266   PetscErrorCode              ierr;
4267   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4268   PetscBool                   flg;
4269   MatSolverTypeForSpecifcType inext,iprev = NULL;
4270 
4271   PetscFunctionBegin;
4272   ierr = MatInitializePackage();CHKERRQ(ierr);
4273   if (!next) {
4274     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4275     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4276     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4277     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4278     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4279     PetscFunctionReturn(0);
4280   }
4281   while (next) {
4282     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4283     if (flg) {
4284       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4285       inext = next->handlers;
4286       while (inext) {
4287         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4288         if (flg) {
4289           inext->getfactor[(int)ftype-1] = getfactor;
4290           PetscFunctionReturn(0);
4291         }
4292         iprev = inext;
4293         inext = inext->next;
4294       }
4295       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4296       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4297       iprev->next->getfactor[(int)ftype-1] = getfactor;
4298       PetscFunctionReturn(0);
4299     }
4300     prev = next;
4301     next = next->next;
4302   }
4303   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4304   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4305   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4306   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4307   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4308   PetscFunctionReturn(0);
4309 }
4310 
4311 /*@C
4312    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4313 
4314    Input Parameters:
4315 +    package - name of the package, for example petsc or superlu
4316 .    ftype - the type of factorization supported by the package
4317 -    mtype - the matrix type that works with this package
4318 
4319    Output Parameters:
4320 +   foundpackage - PETSC_TRUE if the package was registered
4321 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4322 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4323 
4324     Level: intermediate
4325 
4326 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4327 @*/
4328 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4329 {
4330   PetscErrorCode                 ierr;
4331   MatSolverTypeHolder         next = MatSolverTypeHolders;
4332   PetscBool                      flg;
4333   MatSolverTypeForSpecifcType inext;
4334 
4335   PetscFunctionBegin;
4336   if (foundpackage) *foundpackage = PETSC_FALSE;
4337   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4338   if (getfactor)    *getfactor    = NULL;
4339 
4340   if (package) {
4341     while (next) {
4342       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4343       if (flg) {
4344         if (foundpackage) *foundpackage = PETSC_TRUE;
4345         inext = next->handlers;
4346         while (inext) {
4347           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4348           if (flg) {
4349             if (foundmtype) *foundmtype = PETSC_TRUE;
4350             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4351             PetscFunctionReturn(0);
4352           }
4353           inext = inext->next;
4354         }
4355       }
4356       next = next->next;
4357     }
4358   } else {
4359     while (next) {
4360       inext = next->handlers;
4361       while (inext) {
4362         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4363         if (flg && inext->getfactor[(int)ftype-1]) {
4364           if (foundpackage) *foundpackage = PETSC_TRUE;
4365           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4366           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4367           PetscFunctionReturn(0);
4368         }
4369         inext = inext->next;
4370       }
4371       next = next->next;
4372     }
4373   }
4374   PetscFunctionReturn(0);
4375 }
4376 
4377 PetscErrorCode MatSolverTypeDestroy(void)
4378 {
4379   PetscErrorCode              ierr;
4380   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4381   MatSolverTypeForSpecifcType inext,iprev;
4382 
4383   PetscFunctionBegin;
4384   while (next) {
4385     ierr = PetscFree(next->name);CHKERRQ(ierr);
4386     inext = next->handlers;
4387     while (inext) {
4388       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4389       iprev = inext;
4390       inext = inext->next;
4391       ierr = PetscFree(iprev);CHKERRQ(ierr);
4392     }
4393     prev = next;
4394     next = next->next;
4395     ierr = PetscFree(prev);CHKERRQ(ierr);
4396   }
4397   MatSolverTypeHolders = NULL;
4398   PetscFunctionReturn(0);
4399 }
4400 
4401 /*@C
4402    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4403 
4404    Collective on Mat
4405 
4406    Input Parameters:
4407 +  mat - the matrix
4408 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4409 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4410 
4411    Output Parameters:
4412 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4413 
4414    Notes:
4415       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4416      such as pastix, superlu, mumps etc.
4417 
4418       PETSc must have been ./configure to use the external solver, using the option --download-package
4419 
4420    Level: intermediate
4421 
4422 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4423 @*/
4424 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4425 {
4426   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4427   PetscBool      foundpackage,foundmtype;
4428 
4429   PetscFunctionBegin;
4430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4431   PetscValidType(mat,1);
4432 
4433   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4434   MatCheckPreallocated(mat,1);
4435 
4436   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4437   if (!foundpackage) {
4438     if (type) {
4439       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4440     } else {
4441       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4442     }
4443   }
4444 
4445   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4446   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4447 
4448 #if defined(PETSC_USE_COMPLEX)
4449   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4450 #endif
4451 
4452   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4453   PetscFunctionReturn(0);
4454 }
4455 
4456 /*@C
4457    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4458 
4459    Not Collective
4460 
4461    Input Parameters:
4462 +  mat - the matrix
4463 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4464 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4465 
4466    Output Parameter:
4467 .    flg - PETSC_TRUE if the factorization is available
4468 
4469    Notes:
4470       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4471      such as pastix, superlu, mumps etc.
4472 
4473       PETSc must have been ./configure to use the external solver, using the option --download-package
4474 
4475    Level: intermediate
4476 
4477 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4478 @*/
4479 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4480 {
4481   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4482 
4483   PetscFunctionBegin;
4484   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4485   PetscValidType(mat,1);
4486 
4487   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4488   MatCheckPreallocated(mat,1);
4489 
4490   *flg = PETSC_FALSE;
4491   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4492   if (gconv) {
4493     *flg = PETSC_TRUE;
4494   }
4495   PetscFunctionReturn(0);
4496 }
4497 
4498 #include <petscdmtypes.h>
4499 
4500 /*@
4501    MatDuplicate - Duplicates a matrix including the non-zero structure.
4502 
4503    Collective on Mat
4504 
4505    Input Parameters:
4506 +  mat - the matrix
4507 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4508         See the manual page for MatDuplicateOption for an explanation of these options.
4509 
4510    Output Parameter:
4511 .  M - pointer to place new matrix
4512 
4513    Level: intermediate
4514 
4515    Concepts: matrices^duplicating
4516 
4517    Notes:
4518     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4519 
4520 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4521 @*/
4522 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4523 {
4524   PetscErrorCode ierr;
4525   Mat            B;
4526   PetscInt       i;
4527   DM             dm;
4528   void           (*viewf)(void);
4529 
4530   PetscFunctionBegin;
4531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4532   PetscValidType(mat,1);
4533   PetscValidPointer(M,3);
4534   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4535   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4536   MatCheckPreallocated(mat,1);
4537 
4538   *M = 0;
4539   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4540   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4541   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4542   B    = *M;
4543 
4544   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4545   if (viewf) {
4546     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4547   }
4548 
4549   B->stencil.dim = mat->stencil.dim;
4550   B->stencil.noc = mat->stencil.noc;
4551   for (i=0; i<=mat->stencil.dim; i++) {
4552     B->stencil.dims[i]   = mat->stencil.dims[i];
4553     B->stencil.starts[i] = mat->stencil.starts[i];
4554   }
4555 
4556   B->nooffproczerorows = mat->nooffproczerorows;
4557   B->nooffprocentries  = mat->nooffprocentries;
4558 
4559   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4560   if (dm) {
4561     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4562   }
4563   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4564   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4565   PetscFunctionReturn(0);
4566 }
4567 
4568 /*@
4569    MatGetDiagonal - Gets the diagonal of a matrix.
4570 
4571    Logically Collective on Mat and Vec
4572 
4573    Input Parameters:
4574 +  mat - the matrix
4575 -  v - the vector for storing the diagonal
4576 
4577    Output Parameter:
4578 .  v - the diagonal of the matrix
4579 
4580    Level: intermediate
4581 
4582    Note:
4583    Currently only correct in parallel for square matrices.
4584 
4585    Concepts: matrices^accessing diagonals
4586 
4587 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4588 @*/
4589 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4590 {
4591   PetscErrorCode ierr;
4592 
4593   PetscFunctionBegin;
4594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4595   PetscValidType(mat,1);
4596   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4597   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4598   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4599   MatCheckPreallocated(mat,1);
4600 
4601   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4602   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4603   PetscFunctionReturn(0);
4604 }
4605 
4606 /*@C
4607    MatGetRowMin - Gets the minimum value (of the real part) of each
4608         row of the matrix
4609 
4610    Logically Collective on Mat and Vec
4611 
4612    Input Parameters:
4613 .  mat - the matrix
4614 
4615    Output Parameter:
4616 +  v - the vector for storing the maximums
4617 -  idx - the indices of the column found for each row (optional)
4618 
4619    Level: intermediate
4620 
4621    Notes:
4622     The result of this call are the same as if one converted the matrix to dense format
4623       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4624 
4625     This code is only implemented for a couple of matrix formats.
4626 
4627    Concepts: matrices^getting row maximums
4628 
4629 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4630           MatGetRowMax()
4631 @*/
4632 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4633 {
4634   PetscErrorCode ierr;
4635 
4636   PetscFunctionBegin;
4637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4638   PetscValidType(mat,1);
4639   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4640   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4641   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4642   MatCheckPreallocated(mat,1);
4643 
4644   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4645   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4646   PetscFunctionReturn(0);
4647 }
4648 
4649 /*@C
4650    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4651         row of the matrix
4652 
4653    Logically Collective on Mat and Vec
4654 
4655    Input Parameters:
4656 .  mat - the matrix
4657 
4658    Output Parameter:
4659 +  v - the vector for storing the minimums
4660 -  idx - the indices of the column found for each row (or NULL if not needed)
4661 
4662    Level: intermediate
4663 
4664    Notes:
4665     if a row is completely empty or has only 0.0 values then the idx[] value for that
4666     row is 0 (the first column).
4667 
4668     This code is only implemented for a couple of matrix formats.
4669 
4670    Concepts: matrices^getting row maximums
4671 
4672 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4673 @*/
4674 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4675 {
4676   PetscErrorCode ierr;
4677 
4678   PetscFunctionBegin;
4679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4680   PetscValidType(mat,1);
4681   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4682   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4683   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4684   MatCheckPreallocated(mat,1);
4685   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4686 
4687   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4688   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4689   PetscFunctionReturn(0);
4690 }
4691 
4692 /*@C
4693    MatGetRowMax - Gets the maximum value (of the real part) of each
4694         row of the matrix
4695 
4696    Logically Collective on Mat and Vec
4697 
4698    Input Parameters:
4699 .  mat - the matrix
4700 
4701    Output Parameter:
4702 +  v - the vector for storing the maximums
4703 -  idx - the indices of the column found for each row (optional)
4704 
4705    Level: intermediate
4706 
4707    Notes:
4708     The result of this call are the same as if one converted the matrix to dense format
4709       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4710 
4711     This code is only implemented for a couple of matrix formats.
4712 
4713    Concepts: matrices^getting row maximums
4714 
4715 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4716 @*/
4717 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4718 {
4719   PetscErrorCode ierr;
4720 
4721   PetscFunctionBegin;
4722   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4723   PetscValidType(mat,1);
4724   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4725   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4726   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4727   MatCheckPreallocated(mat,1);
4728 
4729   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4730   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4731   PetscFunctionReturn(0);
4732 }
4733 
4734 /*@C
4735    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4736         row of the matrix
4737 
4738    Logically Collective on Mat and Vec
4739 
4740    Input Parameters:
4741 .  mat - the matrix
4742 
4743    Output Parameter:
4744 +  v - the vector for storing the maximums
4745 -  idx - the indices of the column found for each row (or NULL if not needed)
4746 
4747    Level: intermediate
4748 
4749    Notes:
4750     if a row is completely empty or has only 0.0 values then the idx[] value for that
4751     row is 0 (the first column).
4752 
4753     This code is only implemented for a couple of matrix formats.
4754 
4755    Concepts: matrices^getting row maximums
4756 
4757 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4758 @*/
4759 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4760 {
4761   PetscErrorCode ierr;
4762 
4763   PetscFunctionBegin;
4764   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4765   PetscValidType(mat,1);
4766   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4767   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4768   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4769   MatCheckPreallocated(mat,1);
4770   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4771 
4772   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4773   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4774   PetscFunctionReturn(0);
4775 }
4776 
4777 /*@
4778    MatGetRowSum - Gets the sum of each row of the matrix
4779 
4780    Logically or Neighborhood Collective on Mat and Vec
4781 
4782    Input Parameters:
4783 .  mat - the matrix
4784 
4785    Output Parameter:
4786 .  v - the vector for storing the sum of rows
4787 
4788    Level: intermediate
4789 
4790    Notes:
4791     This code is slow since it is not currently specialized for different formats
4792 
4793    Concepts: matrices^getting row sums
4794 
4795 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4796 @*/
4797 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4798 {
4799   Vec            ones;
4800   PetscErrorCode ierr;
4801 
4802   PetscFunctionBegin;
4803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4804   PetscValidType(mat,1);
4805   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4806   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4807   MatCheckPreallocated(mat,1);
4808   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4809   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4810   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4811   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4812   PetscFunctionReturn(0);
4813 }
4814 
4815 /*@
4816    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4817 
4818    Collective on Mat
4819 
4820    Input Parameter:
4821 +  mat - the matrix to transpose
4822 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4823 
4824    Output Parameters:
4825 .  B - the transpose
4826 
4827    Notes:
4828      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4829 
4830      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4831 
4832      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4833 
4834    Level: intermediate
4835 
4836    Concepts: matrices^transposing
4837 
4838 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4839 @*/
4840 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4841 {
4842   PetscErrorCode ierr;
4843 
4844   PetscFunctionBegin;
4845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4846   PetscValidType(mat,1);
4847   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4848   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4849   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4850   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4851   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4852   MatCheckPreallocated(mat,1);
4853 
4854   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4855   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4856   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4857   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4858   PetscFunctionReturn(0);
4859 }
4860 
4861 /*@
4862    MatIsTranspose - Test whether a matrix is another one's transpose,
4863         or its own, in which case it tests symmetry.
4864 
4865    Collective on Mat
4866 
4867    Input Parameter:
4868 +  A - the matrix to test
4869 -  B - the matrix to test against, this can equal the first parameter
4870 
4871    Output Parameters:
4872 .  flg - the result
4873 
4874    Notes:
4875    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4876    has a running time of the order of the number of nonzeros; the parallel
4877    test involves parallel copies of the block-offdiagonal parts of the matrix.
4878 
4879    Level: intermediate
4880 
4881    Concepts: matrices^transposing, matrix^symmetry
4882 
4883 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4884 @*/
4885 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4886 {
4887   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4888 
4889   PetscFunctionBegin;
4890   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4891   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4892   PetscValidPointer(flg,3);
4893   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4894   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4895   *flg = PETSC_FALSE;
4896   if (f && g) {
4897     if (f == g) {
4898       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4899     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4900   } else {
4901     MatType mattype;
4902     if (!f) {
4903       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4904     } else {
4905       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4906     }
4907     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4908   }
4909   PetscFunctionReturn(0);
4910 }
4911 
4912 /*@
4913    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4914 
4915    Collective on Mat
4916 
4917    Input Parameter:
4918 +  mat - the matrix to transpose and complex conjugate
4919 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4920 
4921    Output Parameters:
4922 .  B - the Hermitian
4923 
4924    Level: intermediate
4925 
4926    Concepts: matrices^transposing, complex conjugatex
4927 
4928 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4929 @*/
4930 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4931 {
4932   PetscErrorCode ierr;
4933 
4934   PetscFunctionBegin;
4935   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4936 #if defined(PETSC_USE_COMPLEX)
4937   ierr = MatConjugate(*B);CHKERRQ(ierr);
4938 #endif
4939   PetscFunctionReturn(0);
4940 }
4941 
4942 /*@
4943    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4944 
4945    Collective on Mat
4946 
4947    Input Parameter:
4948 +  A - the matrix to test
4949 -  B - the matrix to test against, this can equal the first parameter
4950 
4951    Output Parameters:
4952 .  flg - the result
4953 
4954    Notes:
4955    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4956    has a running time of the order of the number of nonzeros; the parallel
4957    test involves parallel copies of the block-offdiagonal parts of the matrix.
4958 
4959    Level: intermediate
4960 
4961    Concepts: matrices^transposing, matrix^symmetry
4962 
4963 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4964 @*/
4965 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4966 {
4967   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4968 
4969   PetscFunctionBegin;
4970   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4971   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4972   PetscValidPointer(flg,3);
4973   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4974   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4975   if (f && g) {
4976     if (f==g) {
4977       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4978     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4979   }
4980   PetscFunctionReturn(0);
4981 }
4982 
4983 /*@
4984    MatPermute - Creates a new matrix with rows and columns permuted from the
4985    original.
4986 
4987    Collective on Mat
4988 
4989    Input Parameters:
4990 +  mat - the matrix to permute
4991 .  row - row permutation, each processor supplies only the permutation for its rows
4992 -  col - column permutation, each processor supplies only the permutation for its columns
4993 
4994    Output Parameters:
4995 .  B - the permuted matrix
4996 
4997    Level: advanced
4998 
4999    Note:
5000    The index sets map from row/col of permuted matrix to row/col of original matrix.
5001    The index sets should be on the same communicator as Mat and have the same local sizes.
5002 
5003    Concepts: matrices^permuting
5004 
5005 .seealso: MatGetOrdering(), ISAllGather()
5006 
5007 @*/
5008 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5009 {
5010   PetscErrorCode ierr;
5011 
5012   PetscFunctionBegin;
5013   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5014   PetscValidType(mat,1);
5015   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5016   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5017   PetscValidPointer(B,4);
5018   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5019   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5020   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5021   MatCheckPreallocated(mat,1);
5022 
5023   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5024   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5025   PetscFunctionReturn(0);
5026 }
5027 
5028 /*@
5029    MatEqual - Compares two matrices.
5030 
5031    Collective on Mat
5032 
5033    Input Parameters:
5034 +  A - the first matrix
5035 -  B - the second matrix
5036 
5037    Output Parameter:
5038 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5039 
5040    Level: intermediate
5041 
5042    Concepts: matrices^equality between
5043 @*/
5044 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5045 {
5046   PetscErrorCode ierr;
5047 
5048   PetscFunctionBegin;
5049   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5050   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5051   PetscValidType(A,1);
5052   PetscValidType(B,2);
5053   PetscValidIntPointer(flg,3);
5054   PetscCheckSameComm(A,1,B,2);
5055   MatCheckPreallocated(B,2);
5056   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5057   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5058   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
5059   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5060   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5061   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
5062   MatCheckPreallocated(A,1);
5063 
5064   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5065   PetscFunctionReturn(0);
5066 }
5067 
5068 /*@
5069    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5070    matrices that are stored as vectors.  Either of the two scaling
5071    matrices can be NULL.
5072 
5073    Collective on Mat
5074 
5075    Input Parameters:
5076 +  mat - the matrix to be scaled
5077 .  l - the left scaling vector (or NULL)
5078 -  r - the right scaling vector (or NULL)
5079 
5080    Notes:
5081    MatDiagonalScale() computes A = LAR, where
5082    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5083    The L scales the rows of the matrix, the R scales the columns of the matrix.
5084 
5085    Level: intermediate
5086 
5087    Concepts: matrices^diagonal scaling
5088    Concepts: diagonal scaling of matrices
5089 
5090 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5091 @*/
5092 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5093 {
5094   PetscErrorCode ierr;
5095 
5096   PetscFunctionBegin;
5097   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5098   PetscValidType(mat,1);
5099   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5100   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5101   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5102   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5103   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5104   MatCheckPreallocated(mat,1);
5105 
5106   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5107   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5108   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5109   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5110 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5111   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5112     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5113   }
5114 #endif
5115   PetscFunctionReturn(0);
5116 }
5117 
5118 /*@
5119     MatScale - Scales all elements of a matrix by a given number.
5120 
5121     Logically Collective on Mat
5122 
5123     Input Parameters:
5124 +   mat - the matrix to be scaled
5125 -   a  - the scaling value
5126 
5127     Output Parameter:
5128 .   mat - the scaled matrix
5129 
5130     Level: intermediate
5131 
5132     Concepts: matrices^scaling all entries
5133 
5134 .seealso: MatDiagonalScale()
5135 @*/
5136 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5137 {
5138   PetscErrorCode ierr;
5139 
5140   PetscFunctionBegin;
5141   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5142   PetscValidType(mat,1);
5143   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5144   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5145   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5146   PetscValidLogicalCollectiveScalar(mat,a,2);
5147   MatCheckPreallocated(mat,1);
5148 
5149   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5150   if (a != (PetscScalar)1.0) {
5151     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5152     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5153 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5154     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5155       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5156     }
5157 #endif
5158   }
5159   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5160   PetscFunctionReturn(0);
5161 }
5162 
5163 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm)
5164 {
5165   PetscErrorCode ierr;
5166 
5167   PetscFunctionBegin;
5168   if (type == NORM_1 || type == NORM_INFINITY) {
5169     Vec l,r;
5170 
5171     ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr);
5172     if (type == NORM_INFINITY) {
5173       ierr = VecSet(r,1.);CHKERRQ(ierr);
5174       ierr = MatMult(A,r,l);CHKERRQ(ierr);
5175       ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr);
5176     } else {
5177       ierr = VecSet(l,1.);CHKERRQ(ierr);
5178       ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr);
5179       ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr);
5180     }
5181     ierr = VecDestroy(&l);CHKERRQ(ierr);
5182     ierr = VecDestroy(&r);CHKERRQ(ierr);
5183   } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type);
5184   PetscFunctionReturn(0);
5185 }
5186 
5187 /*@
5188    MatNorm - Calculates various norms of a matrix.
5189 
5190    Collective on Mat
5191 
5192    Input Parameters:
5193 +  mat - the matrix
5194 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5195 
5196    Output Parameters:
5197 .  nrm - the resulting norm
5198 
5199    Level: intermediate
5200 
5201    Concepts: matrices^norm
5202    Concepts: norm^of matrix
5203 @*/
5204 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5205 {
5206   PetscErrorCode ierr;
5207 
5208   PetscFunctionBegin;
5209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5210   PetscValidType(mat,1);
5211   PetscValidLogicalCollectiveEnum(mat,type,2);
5212   PetscValidScalarPointer(nrm,3);
5213 
5214   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5215   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5216   MatCheckPreallocated(mat,1);
5217 
5218   if (!mat->ops->norm) {
5219     ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr);
5220   } else {
5221     ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5222   }
5223   PetscFunctionReturn(0);
5224 }
5225 
5226 /*
5227      This variable is used to prevent counting of MatAssemblyBegin() that
5228    are called from within a MatAssemblyEnd().
5229 */
5230 static PetscInt MatAssemblyEnd_InUse = 0;
5231 /*@
5232    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5233    be called after completing all calls to MatSetValues().
5234 
5235    Collective on Mat
5236 
5237    Input Parameters:
5238 +  mat - the matrix
5239 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5240 
5241    Notes:
5242    MatSetValues() generally caches the values.  The matrix is ready to
5243    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5244    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5245    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5246    using the matrix.
5247 
5248    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5249    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
5250    a global collective operation requring all processes that share the matrix.
5251 
5252    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5253    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5254    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5255 
5256    Level: beginner
5257 
5258    Concepts: matrices^assembling
5259 
5260 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5261 @*/
5262 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5263 {
5264   PetscErrorCode ierr;
5265 
5266   PetscFunctionBegin;
5267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5268   PetscValidType(mat,1);
5269   MatCheckPreallocated(mat,1);
5270   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5271   if (mat->assembled) {
5272     mat->was_assembled = PETSC_TRUE;
5273     mat->assembled     = PETSC_FALSE;
5274   }
5275   if (!MatAssemblyEnd_InUse) {
5276     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5277     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5278     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5279   } else if (mat->ops->assemblybegin) {
5280     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5281   }
5282   PetscFunctionReturn(0);
5283 }
5284 
5285 /*@
5286    MatAssembled - Indicates if a matrix has been assembled and is ready for
5287      use; for example, in matrix-vector product.
5288 
5289    Not Collective
5290 
5291    Input Parameter:
5292 .  mat - the matrix
5293 
5294    Output Parameter:
5295 .  assembled - PETSC_TRUE or PETSC_FALSE
5296 
5297    Level: advanced
5298 
5299    Concepts: matrices^assembled?
5300 
5301 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5302 @*/
5303 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5304 {
5305   PetscFunctionBegin;
5306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5307   PetscValidType(mat,1);
5308   PetscValidPointer(assembled,2);
5309   *assembled = mat->assembled;
5310   PetscFunctionReturn(0);
5311 }
5312 
5313 /*@
5314    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5315    be called after MatAssemblyBegin().
5316 
5317    Collective on Mat
5318 
5319    Input Parameters:
5320 +  mat - the matrix
5321 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5322 
5323    Options Database Keys:
5324 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5325 .  -mat_view ::ascii_info_detail - Prints more detailed info
5326 .  -mat_view - Prints matrix in ASCII format
5327 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5328 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5329 .  -display <name> - Sets display name (default is host)
5330 .  -draw_pause <sec> - Sets number of seconds to pause after display
5331 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5332 .  -viewer_socket_machine <machine> - Machine to use for socket
5333 .  -viewer_socket_port <port> - Port number to use for socket
5334 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5335 
5336    Notes:
5337    MatSetValues() generally caches the values.  The matrix is ready to
5338    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5339    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5340    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5341    using the matrix.
5342 
5343    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5344    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5345    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5346 
5347    Level: beginner
5348 
5349 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5350 @*/
5351 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5352 {
5353   PetscErrorCode  ierr;
5354   static PetscInt inassm = 0;
5355   PetscBool       flg    = PETSC_FALSE;
5356 
5357   PetscFunctionBegin;
5358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5359   PetscValidType(mat,1);
5360 
5361   inassm++;
5362   MatAssemblyEnd_InUse++;
5363   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5364     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5365     if (mat->ops->assemblyend) {
5366       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5367     }
5368     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5369   } else if (mat->ops->assemblyend) {
5370     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5371   }
5372 
5373   /* Flush assembly is not a true assembly */
5374   if (type != MAT_FLUSH_ASSEMBLY) {
5375     mat->assembled = PETSC_TRUE; mat->num_ass++;
5376   }
5377   mat->insertmode = NOT_SET_VALUES;
5378   MatAssemblyEnd_InUse--;
5379   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5380   if (!mat->symmetric_eternal) {
5381     mat->symmetric_set              = PETSC_FALSE;
5382     mat->hermitian_set              = PETSC_FALSE;
5383     mat->structurally_symmetric_set = PETSC_FALSE;
5384   }
5385 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5386   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5387     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5388   }
5389 #endif
5390   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5391     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5392 
5393     if (mat->checksymmetryonassembly) {
5394       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5395       if (flg) {
5396         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5397       } else {
5398         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5399       }
5400     }
5401     if (mat->nullsp && mat->checknullspaceonassembly) {
5402       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5403     }
5404   }
5405   inassm--;
5406   PetscFunctionReturn(0);
5407 }
5408 
5409 /*@
5410    MatSetOption - Sets a parameter option for a matrix. Some options
5411    may be specific to certain storage formats.  Some options
5412    determine how values will be inserted (or added). Sorted,
5413    row-oriented input will generally assemble the fastest. The default
5414    is row-oriented.
5415 
5416    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5417 
5418    Input Parameters:
5419 +  mat - the matrix
5420 .  option - the option, one of those listed below (and possibly others),
5421 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5422 
5423   Options Describing Matrix Structure:
5424 +    MAT_SPD - symmetric positive definite
5425 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5426 .    MAT_HERMITIAN - transpose is the complex conjugation
5427 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5428 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5429                             you set to be kept with all future use of the matrix
5430                             including after MatAssemblyBegin/End() which could
5431                             potentially change the symmetry structure, i.e. you
5432                             KNOW the matrix will ALWAYS have the property you set.
5433 
5434 
5435    Options For Use with MatSetValues():
5436    Insert a logically dense subblock, which can be
5437 .    MAT_ROW_ORIENTED - row-oriented (default)
5438 
5439    Note these options reflect the data you pass in with MatSetValues(); it has
5440    nothing to do with how the data is stored internally in the matrix
5441    data structure.
5442 
5443    When (re)assembling a matrix, we can restrict the input for
5444    efficiency/debugging purposes.  These options include:
5445 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5446 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5447 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5448 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5449 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5450 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5451         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5452         performance for very large process counts.
5453 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5454         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5455         functions, instead sending only neighbor messages.
5456 
5457    Notes:
5458    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5459 
5460    Some options are relevant only for particular matrix types and
5461    are thus ignored by others.  Other options are not supported by
5462    certain matrix types and will generate an error message if set.
5463 
5464    If using a Fortran 77 module to compute a matrix, one may need to
5465    use the column-oriented option (or convert to the row-oriented
5466    format).
5467 
5468    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5469    that would generate a new entry in the nonzero structure is instead
5470    ignored.  Thus, if memory has not alredy been allocated for this particular
5471    data, then the insertion is ignored. For dense matrices, in which
5472    the entire array is allocated, no entries are ever ignored.
5473    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5474 
5475    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5476    that would generate a new entry in the nonzero structure instead produces
5477    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5478 
5479    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5480    that would generate a new entry that has not been preallocated will
5481    instead produce an error. (Currently supported for AIJ and BAIJ formats
5482    only.) This is a useful flag when debugging matrix memory preallocation.
5483    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5484 
5485    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5486    other processors should be dropped, rather than stashed.
5487    This is useful if you know that the "owning" processor is also
5488    always generating the correct matrix entries, so that PETSc need
5489    not transfer duplicate entries generated on another processor.
5490 
5491    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5492    searches during matrix assembly. When this flag is set, the hash table
5493    is created during the first Matrix Assembly. This hash table is
5494    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5495    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5496    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5497    supported by MATMPIBAIJ format only.
5498 
5499    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5500    are kept in the nonzero structure
5501 
5502    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5503    a zero location in the matrix
5504 
5505    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5506 
5507    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5508         zero row routines and thus improves performance for very large process counts.
5509 
5510    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5511         part of the matrix (since they should match the upper triangular part).
5512 
5513    Notes:
5514     Can only be called after MatSetSizes() and MatSetType() have been set.
5515 
5516    Level: intermediate
5517 
5518    Concepts: matrices^setting options
5519 
5520 .seealso:  MatOption, Mat
5521 
5522 @*/
5523 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5524 {
5525   PetscErrorCode ierr;
5526 
5527   PetscFunctionBegin;
5528   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5529   PetscValidType(mat,1);
5530   if (op > 0) {
5531     PetscValidLogicalCollectiveEnum(mat,op,2);
5532     PetscValidLogicalCollectiveBool(mat,flg,3);
5533   }
5534 
5535   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5536   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5537 
5538   switch (op) {
5539   case MAT_NO_OFF_PROC_ENTRIES:
5540     mat->nooffprocentries = flg;
5541     PetscFunctionReturn(0);
5542     break;
5543   case MAT_SUBSET_OFF_PROC_ENTRIES:
5544     mat->subsetoffprocentries = flg;
5545     PetscFunctionReturn(0);
5546   case MAT_NO_OFF_PROC_ZERO_ROWS:
5547     mat->nooffproczerorows = flg;
5548     PetscFunctionReturn(0);
5549     break;
5550   case MAT_SPD:
5551     mat->spd_set = PETSC_TRUE;
5552     mat->spd     = flg;
5553     if (flg) {
5554       mat->symmetric                  = PETSC_TRUE;
5555       mat->structurally_symmetric     = PETSC_TRUE;
5556       mat->symmetric_set              = PETSC_TRUE;
5557       mat->structurally_symmetric_set = PETSC_TRUE;
5558     }
5559     break;
5560   case MAT_SYMMETRIC:
5561     mat->symmetric = flg;
5562     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5563     mat->symmetric_set              = PETSC_TRUE;
5564     mat->structurally_symmetric_set = flg;
5565 #if !defined(PETSC_USE_COMPLEX)
5566     mat->hermitian     = flg;
5567     mat->hermitian_set = PETSC_TRUE;
5568 #endif
5569     break;
5570   case MAT_HERMITIAN:
5571     mat->hermitian = flg;
5572     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5573     mat->hermitian_set              = PETSC_TRUE;
5574     mat->structurally_symmetric_set = flg;
5575 #if !defined(PETSC_USE_COMPLEX)
5576     mat->symmetric     = flg;
5577     mat->symmetric_set = PETSC_TRUE;
5578 #endif
5579     break;
5580   case MAT_STRUCTURALLY_SYMMETRIC:
5581     mat->structurally_symmetric     = flg;
5582     mat->structurally_symmetric_set = PETSC_TRUE;
5583     break;
5584   case MAT_SYMMETRY_ETERNAL:
5585     mat->symmetric_eternal = flg;
5586     break;
5587   case MAT_STRUCTURE_ONLY:
5588     mat->structure_only = flg;
5589     break;
5590   default:
5591     break;
5592   }
5593   if (mat->ops->setoption) {
5594     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5595   }
5596   PetscFunctionReturn(0);
5597 }
5598 
5599 /*@
5600    MatGetOption - Gets a parameter option that has been set for a matrix.
5601 
5602    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5603 
5604    Input Parameters:
5605 +  mat - the matrix
5606 -  option - the option, this only responds to certain options, check the code for which ones
5607 
5608    Output Parameter:
5609 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5610 
5611     Notes:
5612     Can only be called after MatSetSizes() and MatSetType() have been set.
5613 
5614    Level: intermediate
5615 
5616    Concepts: matrices^setting options
5617 
5618 .seealso:  MatOption, MatSetOption()
5619 
5620 @*/
5621 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5622 {
5623   PetscFunctionBegin;
5624   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5625   PetscValidType(mat,1);
5626 
5627   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5628   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5629 
5630   switch (op) {
5631   case MAT_NO_OFF_PROC_ENTRIES:
5632     *flg = mat->nooffprocentries;
5633     break;
5634   case MAT_NO_OFF_PROC_ZERO_ROWS:
5635     *flg = mat->nooffproczerorows;
5636     break;
5637   case MAT_SYMMETRIC:
5638     *flg = mat->symmetric;
5639     break;
5640   case MAT_HERMITIAN:
5641     *flg = mat->hermitian;
5642     break;
5643   case MAT_STRUCTURALLY_SYMMETRIC:
5644     *flg = mat->structurally_symmetric;
5645     break;
5646   case MAT_SYMMETRY_ETERNAL:
5647     *flg = mat->symmetric_eternal;
5648     break;
5649   case MAT_SPD:
5650     *flg = mat->spd;
5651     break;
5652   default:
5653     break;
5654   }
5655   PetscFunctionReturn(0);
5656 }
5657 
5658 /*@
5659    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5660    this routine retains the old nonzero structure.
5661 
5662    Logically Collective on Mat
5663 
5664    Input Parameters:
5665 .  mat - the matrix
5666 
5667    Level: intermediate
5668 
5669    Notes:
5670     If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5671    See the Performance chapter of the users manual for information on preallocating matrices.
5672 
5673    Concepts: matrices^zeroing
5674 
5675 .seealso: MatZeroRows()
5676 @*/
5677 PetscErrorCode MatZeroEntries(Mat mat)
5678 {
5679   PetscErrorCode ierr;
5680 
5681   PetscFunctionBegin;
5682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5683   PetscValidType(mat,1);
5684   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5685   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5686   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5687   MatCheckPreallocated(mat,1);
5688 
5689   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5690   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5691   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5692   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5693 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5694   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5695     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5696   }
5697 #endif
5698   PetscFunctionReturn(0);
5699 }
5700 
5701 /*@
5702    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5703    of a set of rows and columns of a matrix.
5704 
5705    Collective on Mat
5706 
5707    Input Parameters:
5708 +  mat - the matrix
5709 .  numRows - the number of rows to remove
5710 .  rows - the global row indices
5711 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5712 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5713 -  b - optional vector of right hand side, that will be adjusted by provided solution
5714 
5715    Notes:
5716    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5717 
5718    The user can set a value in the diagonal entry (or for the AIJ and
5719    row formats can optionally remove the main diagonal entry from the
5720    nonzero structure as well, by passing 0.0 as the final argument).
5721 
5722    For the parallel case, all processes that share the matrix (i.e.,
5723    those in the communicator used for matrix creation) MUST call this
5724    routine, regardless of whether any rows being zeroed are owned by
5725    them.
5726 
5727    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5728    list only rows local to itself).
5729 
5730    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5731 
5732    Level: intermediate
5733 
5734    Concepts: matrices^zeroing rows
5735 
5736 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5737           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5738 @*/
5739 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5740 {
5741   PetscErrorCode ierr;
5742 
5743   PetscFunctionBegin;
5744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5745   PetscValidType(mat,1);
5746   if (numRows) PetscValidIntPointer(rows,3);
5747   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5748   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5749   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5750   MatCheckPreallocated(mat,1);
5751 
5752   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5753   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5754   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5755 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5756   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5757     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5758   }
5759 #endif
5760   PetscFunctionReturn(0);
5761 }
5762 
5763 /*@
5764    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5765    of a set of rows and columns of a matrix.
5766 
5767    Collective on Mat
5768 
5769    Input Parameters:
5770 +  mat - the matrix
5771 .  is - the rows to zero
5772 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5773 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5774 -  b - optional vector of right hand side, that will be adjusted by provided solution
5775 
5776    Notes:
5777    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5778 
5779    The user can set a value in the diagonal entry (or for the AIJ and
5780    row formats can optionally remove the main diagonal entry from the
5781    nonzero structure as well, by passing 0.0 as the final argument).
5782 
5783    For the parallel case, all processes that share the matrix (i.e.,
5784    those in the communicator used for matrix creation) MUST call this
5785    routine, regardless of whether any rows being zeroed are owned by
5786    them.
5787 
5788    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5789    list only rows local to itself).
5790 
5791    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5792 
5793    Level: intermediate
5794 
5795    Concepts: matrices^zeroing rows
5796 
5797 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5798           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5799 @*/
5800 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5801 {
5802   PetscErrorCode ierr;
5803   PetscInt       numRows;
5804   const PetscInt *rows;
5805 
5806   PetscFunctionBegin;
5807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5808   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5809   PetscValidType(mat,1);
5810   PetscValidType(is,2);
5811   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5812   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5813   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5814   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5815   PetscFunctionReturn(0);
5816 }
5817 
5818 /*@
5819    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5820    of a set of rows of a matrix.
5821 
5822    Collective on Mat
5823 
5824    Input Parameters:
5825 +  mat - the matrix
5826 .  numRows - the number of rows to remove
5827 .  rows - the global row indices
5828 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5829 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5830 -  b - optional vector of right hand side, that will be adjusted by provided solution
5831 
5832    Notes:
5833    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5834    but does not release memory.  For the dense and block diagonal
5835    formats this does not alter the nonzero structure.
5836 
5837    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5838    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5839    merely zeroed.
5840 
5841    The user can set a value in the diagonal entry (or for the AIJ and
5842    row formats can optionally remove the main diagonal entry from the
5843    nonzero structure as well, by passing 0.0 as the final argument).
5844 
5845    For the parallel case, all processes that share the matrix (i.e.,
5846    those in the communicator used for matrix creation) MUST call this
5847    routine, regardless of whether any rows being zeroed are owned by
5848    them.
5849 
5850    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5851    list only rows local to itself).
5852 
5853    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5854    owns that are to be zeroed. This saves a global synchronization in the implementation.
5855 
5856    Level: intermediate
5857 
5858    Concepts: matrices^zeroing rows
5859 
5860 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5861           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5862 @*/
5863 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5864 {
5865   PetscErrorCode ierr;
5866 
5867   PetscFunctionBegin;
5868   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5869   PetscValidType(mat,1);
5870   if (numRows) PetscValidIntPointer(rows,3);
5871   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5872   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5873   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5874   MatCheckPreallocated(mat,1);
5875 
5876   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5877   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5878   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5879 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5880   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5881     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5882   }
5883 #endif
5884   PetscFunctionReturn(0);
5885 }
5886 
5887 /*@
5888    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5889    of a set of rows of a matrix.
5890 
5891    Collective on Mat
5892 
5893    Input Parameters:
5894 +  mat - the matrix
5895 .  is - index set of rows to remove
5896 .  diag - value put in all diagonals of eliminated rows
5897 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5898 -  b - optional vector of right hand side, that will be adjusted by provided solution
5899 
5900    Notes:
5901    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5902    but does not release memory.  For the dense and block diagonal
5903    formats this does not alter the nonzero structure.
5904 
5905    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5906    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5907    merely zeroed.
5908 
5909    The user can set a value in the diagonal entry (or for the AIJ and
5910    row formats can optionally remove the main diagonal entry from the
5911    nonzero structure as well, by passing 0.0 as the final argument).
5912 
5913    For the parallel case, all processes that share the matrix (i.e.,
5914    those in the communicator used for matrix creation) MUST call this
5915    routine, regardless of whether any rows being zeroed are owned by
5916    them.
5917 
5918    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5919    list only rows local to itself).
5920 
5921    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5922    owns that are to be zeroed. This saves a global synchronization in the implementation.
5923 
5924    Level: intermediate
5925 
5926    Concepts: matrices^zeroing rows
5927 
5928 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5929           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5930 @*/
5931 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5932 {
5933   PetscInt       numRows;
5934   const PetscInt *rows;
5935   PetscErrorCode ierr;
5936 
5937   PetscFunctionBegin;
5938   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5939   PetscValidType(mat,1);
5940   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5941   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5942   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5943   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5944   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5945   PetscFunctionReturn(0);
5946 }
5947 
5948 /*@
5949    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5950    of a set of rows of a matrix. These rows must be local to the process.
5951 
5952    Collective on Mat
5953 
5954    Input Parameters:
5955 +  mat - the matrix
5956 .  numRows - the number of rows to remove
5957 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5958 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5959 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5960 -  b - optional vector of right hand side, that will be adjusted by provided solution
5961 
5962    Notes:
5963    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5964    but does not release memory.  For the dense and block diagonal
5965    formats this does not alter the nonzero structure.
5966 
5967    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5968    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5969    merely zeroed.
5970 
5971    The user can set a value in the diagonal entry (or for the AIJ and
5972    row formats can optionally remove the main diagonal entry from the
5973    nonzero structure as well, by passing 0.0 as the final argument).
5974 
5975    For the parallel case, all processes that share the matrix (i.e.,
5976    those in the communicator used for matrix creation) MUST call this
5977    routine, regardless of whether any rows being zeroed are owned by
5978    them.
5979 
5980    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5981    list only rows local to itself).
5982 
5983    The grid coordinates are across the entire grid, not just the local portion
5984 
5985    In Fortran idxm and idxn should be declared as
5986 $     MatStencil idxm(4,m)
5987    and the values inserted using
5988 $    idxm(MatStencil_i,1) = i
5989 $    idxm(MatStencil_j,1) = j
5990 $    idxm(MatStencil_k,1) = k
5991 $    idxm(MatStencil_c,1) = c
5992    etc
5993 
5994    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5995    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5996    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5997    DM_BOUNDARY_PERIODIC boundary type.
5998 
5999    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
6000    a single value per point) you can skip filling those indices.
6001 
6002    Level: intermediate
6003 
6004    Concepts: matrices^zeroing rows
6005 
6006 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6007           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6008 @*/
6009 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6010 {
6011   PetscInt       dim     = mat->stencil.dim;
6012   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6013   PetscInt       *dims   = mat->stencil.dims+1;
6014   PetscInt       *starts = mat->stencil.starts;
6015   PetscInt       *dxm    = (PetscInt*) rows;
6016   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6017   PetscErrorCode ierr;
6018 
6019   PetscFunctionBegin;
6020   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6021   PetscValidType(mat,1);
6022   if (numRows) PetscValidIntPointer(rows,3);
6023 
6024   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6025   for (i = 0; i < numRows; ++i) {
6026     /* Skip unused dimensions (they are ordered k, j, i, c) */
6027     for (j = 0; j < 3-sdim; ++j) dxm++;
6028     /* Local index in X dir */
6029     tmp = *dxm++ - starts[0];
6030     /* Loop over remaining dimensions */
6031     for (j = 0; j < dim-1; ++j) {
6032       /* If nonlocal, set index to be negative */
6033       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6034       /* Update local index */
6035       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6036     }
6037     /* Skip component slot if necessary */
6038     if (mat->stencil.noc) dxm++;
6039     /* Local row number */
6040     if (tmp >= 0) {
6041       jdxm[numNewRows++] = tmp;
6042     }
6043   }
6044   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6045   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6046   PetscFunctionReturn(0);
6047 }
6048 
6049 /*@
6050    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6051    of a set of rows and columns of a matrix.
6052 
6053    Collective on Mat
6054 
6055    Input Parameters:
6056 +  mat - the matrix
6057 .  numRows - the number of rows/columns to remove
6058 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6059 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6060 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6061 -  b - optional vector of right hand side, that will be adjusted by provided solution
6062 
6063    Notes:
6064    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6065    but does not release memory.  For the dense and block diagonal
6066    formats this does not alter the nonzero structure.
6067 
6068    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6069    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6070    merely zeroed.
6071 
6072    The user can set a value in the diagonal entry (or for the AIJ and
6073    row formats can optionally remove the main diagonal entry from the
6074    nonzero structure as well, by passing 0.0 as the final argument).
6075 
6076    For the parallel case, all processes that share the matrix (i.e.,
6077    those in the communicator used for matrix creation) MUST call this
6078    routine, regardless of whether any rows being zeroed are owned by
6079    them.
6080 
6081    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6082    list only rows local to itself, but the row/column numbers are given in local numbering).
6083 
6084    The grid coordinates are across the entire grid, not just the local portion
6085 
6086    In Fortran idxm and idxn should be declared as
6087 $     MatStencil idxm(4,m)
6088    and the values inserted using
6089 $    idxm(MatStencil_i,1) = i
6090 $    idxm(MatStencil_j,1) = j
6091 $    idxm(MatStencil_k,1) = k
6092 $    idxm(MatStencil_c,1) = c
6093    etc
6094 
6095    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6096    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6097    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6098    DM_BOUNDARY_PERIODIC boundary type.
6099 
6100    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
6101    a single value per point) you can skip filling those indices.
6102 
6103    Level: intermediate
6104 
6105    Concepts: matrices^zeroing rows
6106 
6107 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6108           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6109 @*/
6110 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6111 {
6112   PetscInt       dim     = mat->stencil.dim;
6113   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6114   PetscInt       *dims   = mat->stencil.dims+1;
6115   PetscInt       *starts = mat->stencil.starts;
6116   PetscInt       *dxm    = (PetscInt*) rows;
6117   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6118   PetscErrorCode ierr;
6119 
6120   PetscFunctionBegin;
6121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6122   PetscValidType(mat,1);
6123   if (numRows) PetscValidIntPointer(rows,3);
6124 
6125   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6126   for (i = 0; i < numRows; ++i) {
6127     /* Skip unused dimensions (they are ordered k, j, i, c) */
6128     for (j = 0; j < 3-sdim; ++j) dxm++;
6129     /* Local index in X dir */
6130     tmp = *dxm++ - starts[0];
6131     /* Loop over remaining dimensions */
6132     for (j = 0; j < dim-1; ++j) {
6133       /* If nonlocal, set index to be negative */
6134       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6135       /* Update local index */
6136       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6137     }
6138     /* Skip component slot if necessary */
6139     if (mat->stencil.noc) dxm++;
6140     /* Local row number */
6141     if (tmp >= 0) {
6142       jdxm[numNewRows++] = tmp;
6143     }
6144   }
6145   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6146   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6147   PetscFunctionReturn(0);
6148 }
6149 
6150 /*@C
6151    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6152    of a set of rows of a matrix; using local numbering of rows.
6153 
6154    Collective on Mat
6155 
6156    Input Parameters:
6157 +  mat - the matrix
6158 .  numRows - the number of rows to remove
6159 .  rows - the global row indices
6160 .  diag - value put in all diagonals of eliminated rows
6161 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6162 -  b - optional vector of right hand side, that will be adjusted by provided solution
6163 
6164    Notes:
6165    Before calling MatZeroRowsLocal(), the user must first set the
6166    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6167 
6168    For the AIJ matrix formats this removes the old nonzero structure,
6169    but does not release memory.  For the dense and block diagonal
6170    formats this does not alter the nonzero structure.
6171 
6172    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6173    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6174    merely zeroed.
6175 
6176    The user can set a value in the diagonal entry (or for the AIJ and
6177    row formats can optionally remove the main diagonal entry from the
6178    nonzero structure as well, by passing 0.0 as the final argument).
6179 
6180    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6181    owns that are to be zeroed. This saves a global synchronization in the implementation.
6182 
6183    Level: intermediate
6184 
6185    Concepts: matrices^zeroing
6186 
6187 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6188           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6189 @*/
6190 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6191 {
6192   PetscErrorCode ierr;
6193 
6194   PetscFunctionBegin;
6195   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6196   PetscValidType(mat,1);
6197   if (numRows) PetscValidIntPointer(rows,3);
6198   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6199   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6200   MatCheckPreallocated(mat,1);
6201 
6202   if (mat->ops->zerorowslocal) {
6203     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6204   } else {
6205     IS             is, newis;
6206     const PetscInt *newRows;
6207 
6208     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6209     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6210     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6211     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6212     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6213     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6214     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6215     ierr = ISDestroy(&is);CHKERRQ(ierr);
6216   }
6217   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6218 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6219   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6220     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6221   }
6222 #endif
6223   PetscFunctionReturn(0);
6224 }
6225 
6226 /*@
6227    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6228    of a set of rows of a matrix; using local numbering of rows.
6229 
6230    Collective on Mat
6231 
6232    Input Parameters:
6233 +  mat - the matrix
6234 .  is - index set of rows to remove
6235 .  diag - value put in all diagonals of eliminated rows
6236 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6237 -  b - optional vector of right hand side, that will be adjusted by provided solution
6238 
6239    Notes:
6240    Before calling MatZeroRowsLocalIS(), the user must first set the
6241    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6242 
6243    For the AIJ matrix formats this removes the old nonzero structure,
6244    but does not release memory.  For the dense and block diagonal
6245    formats this does not alter the nonzero structure.
6246 
6247    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6248    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6249    merely zeroed.
6250 
6251    The user can set a value in the diagonal entry (or for the AIJ and
6252    row formats can optionally remove the main diagonal entry from the
6253    nonzero structure as well, by passing 0.0 as the final argument).
6254 
6255    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6256    owns that are to be zeroed. This saves a global synchronization in the implementation.
6257 
6258    Level: intermediate
6259 
6260    Concepts: matrices^zeroing
6261 
6262 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6263           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6264 @*/
6265 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6266 {
6267   PetscErrorCode ierr;
6268   PetscInt       numRows;
6269   const PetscInt *rows;
6270 
6271   PetscFunctionBegin;
6272   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6273   PetscValidType(mat,1);
6274   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6275   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6276   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6277   MatCheckPreallocated(mat,1);
6278 
6279   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6280   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6281   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6282   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6283   PetscFunctionReturn(0);
6284 }
6285 
6286 /*@
6287    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6288    of a set of rows and columns of a matrix; using local numbering of rows.
6289 
6290    Collective on Mat
6291 
6292    Input Parameters:
6293 +  mat - the matrix
6294 .  numRows - the number of rows to remove
6295 .  rows - the global row indices
6296 .  diag - value put in all diagonals of eliminated rows
6297 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6298 -  b - optional vector of right hand side, that will be adjusted by provided solution
6299 
6300    Notes:
6301    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6302    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6303 
6304    The user can set a value in the diagonal entry (or for the AIJ and
6305    row formats can optionally remove the main diagonal entry from the
6306    nonzero structure as well, by passing 0.0 as the final argument).
6307 
6308    Level: intermediate
6309 
6310    Concepts: matrices^zeroing
6311 
6312 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6313           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6314 @*/
6315 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6316 {
6317   PetscErrorCode ierr;
6318   IS             is, newis;
6319   const PetscInt *newRows;
6320 
6321   PetscFunctionBegin;
6322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6323   PetscValidType(mat,1);
6324   if (numRows) PetscValidIntPointer(rows,3);
6325   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6326   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6327   MatCheckPreallocated(mat,1);
6328 
6329   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6330   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6331   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6332   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6333   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6334   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6335   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6336   ierr = ISDestroy(&is);CHKERRQ(ierr);
6337   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6338 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6339   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6340     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6341   }
6342 #endif
6343   PetscFunctionReturn(0);
6344 }
6345 
6346 /*@
6347    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6348    of a set of rows and columns of a matrix; using local numbering of rows.
6349 
6350    Collective on Mat
6351 
6352    Input Parameters:
6353 +  mat - the matrix
6354 .  is - index set of rows to remove
6355 .  diag - value put in all diagonals of eliminated rows
6356 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6357 -  b - optional vector of right hand side, that will be adjusted by provided solution
6358 
6359    Notes:
6360    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6361    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6362 
6363    The user can set a value in the diagonal entry (or for the AIJ and
6364    row formats can optionally remove the main diagonal entry from the
6365    nonzero structure as well, by passing 0.0 as the final argument).
6366 
6367    Level: intermediate
6368 
6369    Concepts: matrices^zeroing
6370 
6371 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6372           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6373 @*/
6374 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6375 {
6376   PetscErrorCode ierr;
6377   PetscInt       numRows;
6378   const PetscInt *rows;
6379 
6380   PetscFunctionBegin;
6381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6382   PetscValidType(mat,1);
6383   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6385   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6386   MatCheckPreallocated(mat,1);
6387 
6388   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6389   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6390   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6391   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6392   PetscFunctionReturn(0);
6393 }
6394 
6395 /*@C
6396    MatGetSize - Returns the numbers of rows and columns in a matrix.
6397 
6398    Not Collective
6399 
6400    Input Parameter:
6401 .  mat - the matrix
6402 
6403    Output Parameters:
6404 +  m - the number of global rows
6405 -  n - the number of global columns
6406 
6407    Note: both output parameters can be NULL on input.
6408 
6409    Level: beginner
6410 
6411    Concepts: matrices^size
6412 
6413 .seealso: MatGetLocalSize()
6414 @*/
6415 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6416 {
6417   PetscFunctionBegin;
6418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6419   if (m) *m = mat->rmap->N;
6420   if (n) *n = mat->cmap->N;
6421   PetscFunctionReturn(0);
6422 }
6423 
6424 /*@C
6425    MatGetLocalSize - Returns the number of rows and columns in a matrix
6426    stored locally.  This information may be implementation dependent, so
6427    use with care.
6428 
6429    Not Collective
6430 
6431    Input Parameters:
6432 .  mat - the matrix
6433 
6434    Output Parameters:
6435 +  m - the number of local rows
6436 -  n - the number of local columns
6437 
6438    Note: both output parameters can be NULL on input.
6439 
6440    Level: beginner
6441 
6442    Concepts: matrices^local size
6443 
6444 .seealso: MatGetSize()
6445 @*/
6446 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6447 {
6448   PetscFunctionBegin;
6449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6450   if (m) PetscValidIntPointer(m,2);
6451   if (n) PetscValidIntPointer(n,3);
6452   if (m) *m = mat->rmap->n;
6453   if (n) *n = mat->cmap->n;
6454   PetscFunctionReturn(0);
6455 }
6456 
6457 /*@C
6458    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6459    this processor. (The columns of the "diagonal block")
6460 
6461    Not Collective, unless matrix has not been allocated, then collective on Mat
6462 
6463    Input Parameters:
6464 .  mat - the matrix
6465 
6466    Output Parameters:
6467 +  m - the global index of the first local column
6468 -  n - one more than the global index of the last local column
6469 
6470    Notes:
6471     both output parameters can be NULL on input.
6472 
6473    Level: developer
6474 
6475    Concepts: matrices^column ownership
6476 
6477 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6478 
6479 @*/
6480 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6481 {
6482   PetscFunctionBegin;
6483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6484   PetscValidType(mat,1);
6485   if (m) PetscValidIntPointer(m,2);
6486   if (n) PetscValidIntPointer(n,3);
6487   MatCheckPreallocated(mat,1);
6488   if (m) *m = mat->cmap->rstart;
6489   if (n) *n = mat->cmap->rend;
6490   PetscFunctionReturn(0);
6491 }
6492 
6493 /*@C
6494    MatGetOwnershipRange - Returns the range of matrix rows owned by
6495    this processor, assuming that the matrix is laid out with the first
6496    n1 rows on the first processor, the next n2 rows on the second, etc.
6497    For certain parallel layouts this range may not be well defined.
6498 
6499    Not Collective
6500 
6501    Input Parameters:
6502 .  mat - the matrix
6503 
6504    Output Parameters:
6505 +  m - the global index of the first local row
6506 -  n - one more than the global index of the last local row
6507 
6508    Note: Both output parameters can be NULL on input.
6509 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6510 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6511 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6512 
6513    Level: beginner
6514 
6515    Concepts: matrices^row ownership
6516 
6517 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6518 
6519 @*/
6520 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6521 {
6522   PetscFunctionBegin;
6523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6524   PetscValidType(mat,1);
6525   if (m) PetscValidIntPointer(m,2);
6526   if (n) PetscValidIntPointer(n,3);
6527   MatCheckPreallocated(mat,1);
6528   if (m) *m = mat->rmap->rstart;
6529   if (n) *n = mat->rmap->rend;
6530   PetscFunctionReturn(0);
6531 }
6532 
6533 /*@C
6534    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6535    each process
6536 
6537    Not Collective, unless matrix has not been allocated, then collective on Mat
6538 
6539    Input Parameters:
6540 .  mat - the matrix
6541 
6542    Output Parameters:
6543 .  ranges - start of each processors portion plus one more than the total length at the end
6544 
6545    Level: beginner
6546 
6547    Concepts: matrices^row ownership
6548 
6549 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6550 
6551 @*/
6552 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6553 {
6554   PetscErrorCode ierr;
6555 
6556   PetscFunctionBegin;
6557   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6558   PetscValidType(mat,1);
6559   MatCheckPreallocated(mat,1);
6560   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6561   PetscFunctionReturn(0);
6562 }
6563 
6564 /*@C
6565    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6566    this processor. (The columns of the "diagonal blocks" for each process)
6567 
6568    Not Collective, unless matrix has not been allocated, then collective on Mat
6569 
6570    Input Parameters:
6571 .  mat - the matrix
6572 
6573    Output Parameters:
6574 .  ranges - start of each processors portion plus one more then the total length at the end
6575 
6576    Level: beginner
6577 
6578    Concepts: matrices^column ownership
6579 
6580 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6581 
6582 @*/
6583 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6584 {
6585   PetscErrorCode ierr;
6586 
6587   PetscFunctionBegin;
6588   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6589   PetscValidType(mat,1);
6590   MatCheckPreallocated(mat,1);
6591   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6592   PetscFunctionReturn(0);
6593 }
6594 
6595 /*@C
6596    MatGetOwnershipIS - Get row and column ownership as index sets
6597 
6598    Not Collective
6599 
6600    Input Arguments:
6601 .  A - matrix of type Elemental
6602 
6603    Output Arguments:
6604 +  rows - rows in which this process owns elements
6605 .  cols - columns in which this process owns elements
6606 
6607    Level: intermediate
6608 
6609 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6610 @*/
6611 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6612 {
6613   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6614 
6615   PetscFunctionBegin;
6616   MatCheckPreallocated(A,1);
6617   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6618   if (f) {
6619     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6620   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6621     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6622     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6623   }
6624   PetscFunctionReturn(0);
6625 }
6626 
6627 /*@C
6628    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6629    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6630    to complete the factorization.
6631 
6632    Collective on Mat
6633 
6634    Input Parameters:
6635 +  mat - the matrix
6636 .  row - row permutation
6637 .  column - column permutation
6638 -  info - structure containing
6639 $      levels - number of levels of fill.
6640 $      expected fill - as ratio of original fill.
6641 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6642                 missing diagonal entries)
6643 
6644    Output Parameters:
6645 .  fact - new matrix that has been symbolically factored
6646 
6647    Notes:
6648     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6649 
6650    Most users should employ the simplified KSP interface for linear solvers
6651    instead of working directly with matrix algebra routines such as this.
6652    See, e.g., KSPCreate().
6653 
6654    Level: developer
6655 
6656   Concepts: matrices^symbolic LU factorization
6657   Concepts: matrices^factorization
6658   Concepts: LU^symbolic factorization
6659 
6660 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6661           MatGetOrdering(), MatFactorInfo
6662 
6663     Developer Note: fortran interface is not autogenerated as the f90
6664     interface defintion cannot be generated correctly [due to MatFactorInfo]
6665 
6666 @*/
6667 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6668 {
6669   PetscErrorCode ierr;
6670 
6671   PetscFunctionBegin;
6672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6673   PetscValidType(mat,1);
6674   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6675   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6676   PetscValidPointer(info,4);
6677   PetscValidPointer(fact,5);
6678   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6679   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6680   if (!(fact)->ops->ilufactorsymbolic) {
6681     MatSolverType spackage;
6682     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6683     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6684   }
6685   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6686   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6687   MatCheckPreallocated(mat,2);
6688 
6689   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6690   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6691   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6692   PetscFunctionReturn(0);
6693 }
6694 
6695 /*@C
6696    MatICCFactorSymbolic - Performs symbolic incomplete
6697    Cholesky factorization for a symmetric matrix.  Use
6698    MatCholeskyFactorNumeric() to complete the factorization.
6699 
6700    Collective on Mat
6701 
6702    Input Parameters:
6703 +  mat - the matrix
6704 .  perm - row and column permutation
6705 -  info - structure containing
6706 $      levels - number of levels of fill.
6707 $      expected fill - as ratio of original fill.
6708 
6709    Output Parameter:
6710 .  fact - the factored matrix
6711 
6712    Notes:
6713    Most users should employ the KSP interface for linear solvers
6714    instead of working directly with matrix algebra routines such as this.
6715    See, e.g., KSPCreate().
6716 
6717    Level: developer
6718 
6719   Concepts: matrices^symbolic incomplete Cholesky factorization
6720   Concepts: matrices^factorization
6721   Concepts: Cholsky^symbolic factorization
6722 
6723 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6724 
6725     Developer Note: fortran interface is not autogenerated as the f90
6726     interface defintion cannot be generated correctly [due to MatFactorInfo]
6727 
6728 @*/
6729 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6730 {
6731   PetscErrorCode ierr;
6732 
6733   PetscFunctionBegin;
6734   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6735   PetscValidType(mat,1);
6736   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6737   PetscValidPointer(info,3);
6738   PetscValidPointer(fact,4);
6739   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6740   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6741   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6742   if (!(fact)->ops->iccfactorsymbolic) {
6743     MatSolverType spackage;
6744     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6745     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6746   }
6747   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6748   MatCheckPreallocated(mat,2);
6749 
6750   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6751   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6752   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6753   PetscFunctionReturn(0);
6754 }
6755 
6756 /*@C
6757    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6758    points to an array of valid matrices, they may be reused to store the new
6759    submatrices.
6760 
6761    Collective on Mat
6762 
6763    Input Parameters:
6764 +  mat - the matrix
6765 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6766 .  irow, icol - index sets of rows and columns to extract
6767 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6768 
6769    Output Parameter:
6770 .  submat - the array of submatrices
6771 
6772    Notes:
6773    MatCreateSubMatrices() can extract ONLY sequential submatrices
6774    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6775    to extract a parallel submatrix.
6776 
6777    Some matrix types place restrictions on the row and column
6778    indices, such as that they be sorted or that they be equal to each other.
6779 
6780    The index sets may not have duplicate entries.
6781 
6782    When extracting submatrices from a parallel matrix, each processor can
6783    form a different submatrix by setting the rows and columns of its
6784    individual index sets according to the local submatrix desired.
6785 
6786    When finished using the submatrices, the user should destroy
6787    them with MatDestroySubMatrices().
6788 
6789    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6790    original matrix has not changed from that last call to MatCreateSubMatrices().
6791 
6792    This routine creates the matrices in submat; you should NOT create them before
6793    calling it. It also allocates the array of matrix pointers submat.
6794 
6795    For BAIJ matrices the index sets must respect the block structure, that is if they
6796    request one row/column in a block, they must request all rows/columns that are in
6797    that block. For example, if the block size is 2 you cannot request just row 0 and
6798    column 0.
6799 
6800    Fortran Note:
6801    The Fortran interface is slightly different from that given below; it
6802    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6803 
6804    Level: advanced
6805 
6806    Concepts: matrices^accessing submatrices
6807    Concepts: submatrices
6808 
6809 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6810 @*/
6811 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6812 {
6813   PetscErrorCode ierr;
6814   PetscInt       i;
6815   PetscBool      eq;
6816 
6817   PetscFunctionBegin;
6818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6819   PetscValidType(mat,1);
6820   if (n) {
6821     PetscValidPointer(irow,3);
6822     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6823     PetscValidPointer(icol,4);
6824     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6825   }
6826   PetscValidPointer(submat,6);
6827   if (n && scall == MAT_REUSE_MATRIX) {
6828     PetscValidPointer(*submat,6);
6829     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6830   }
6831   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6832   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6833   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6834   MatCheckPreallocated(mat,1);
6835 
6836   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6837   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6838   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6839   for (i=0; i<n; i++) {
6840     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6841     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6842       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6843       if (eq) {
6844         if (mat->symmetric) {
6845           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6846         } else if (mat->hermitian) {
6847           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6848         } else if (mat->structurally_symmetric) {
6849           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6850         }
6851       }
6852     }
6853   }
6854   PetscFunctionReturn(0);
6855 }
6856 
6857 /*@C
6858    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6859 
6860    Collective on Mat
6861 
6862    Input Parameters:
6863 +  mat - the matrix
6864 .  n   - the number of submatrixes to be extracted
6865 .  irow, icol - index sets of rows and columns to extract
6866 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6867 
6868    Output Parameter:
6869 .  submat - the array of submatrices
6870 
6871    Level: advanced
6872 
6873    Concepts: matrices^accessing submatrices
6874    Concepts: submatrices
6875 
6876 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6877 @*/
6878 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6879 {
6880   PetscErrorCode ierr;
6881   PetscInt       i;
6882   PetscBool      eq;
6883 
6884   PetscFunctionBegin;
6885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6886   PetscValidType(mat,1);
6887   if (n) {
6888     PetscValidPointer(irow,3);
6889     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6890     PetscValidPointer(icol,4);
6891     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6892   }
6893   PetscValidPointer(submat,6);
6894   if (n && scall == MAT_REUSE_MATRIX) {
6895     PetscValidPointer(*submat,6);
6896     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6897   }
6898   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6899   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6900   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6901   MatCheckPreallocated(mat,1);
6902 
6903   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6904   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6905   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6906   for (i=0; i<n; i++) {
6907     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6908       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6909       if (eq) {
6910         if (mat->symmetric) {
6911           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6912         } else if (mat->hermitian) {
6913           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6914         } else if (mat->structurally_symmetric) {
6915           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6916         }
6917       }
6918     }
6919   }
6920   PetscFunctionReturn(0);
6921 }
6922 
6923 /*@C
6924    MatDestroyMatrices - Destroys an array of matrices.
6925 
6926    Collective on Mat
6927 
6928    Input Parameters:
6929 +  n - the number of local matrices
6930 -  mat - the matrices (note that this is a pointer to the array of matrices)
6931 
6932    Level: advanced
6933 
6934     Notes:
6935     Frees not only the matrices, but also the array that contains the matrices
6936            In Fortran will not free the array.
6937 
6938 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6939 @*/
6940 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6941 {
6942   PetscErrorCode ierr;
6943   PetscInt       i;
6944 
6945   PetscFunctionBegin;
6946   if (!*mat) PetscFunctionReturn(0);
6947   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6948   PetscValidPointer(mat,2);
6949 
6950   for (i=0; i<n; i++) {
6951     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6952   }
6953 
6954   /* memory is allocated even if n = 0 */
6955   ierr = PetscFree(*mat);CHKERRQ(ierr);
6956   PetscFunctionReturn(0);
6957 }
6958 
6959 /*@C
6960    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6961 
6962    Collective on Mat
6963 
6964    Input Parameters:
6965 +  n - the number of local matrices
6966 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6967                        sequence of MatCreateSubMatrices())
6968 
6969    Level: advanced
6970 
6971     Notes:
6972     Frees not only the matrices, but also the array that contains the matrices
6973            In Fortran will not free the array.
6974 
6975 .seealso: MatCreateSubMatrices()
6976 @*/
6977 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6978 {
6979   PetscErrorCode ierr;
6980   Mat            mat0;
6981 
6982   PetscFunctionBegin;
6983   if (!*mat) PetscFunctionReturn(0);
6984   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6985   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6986   PetscValidPointer(mat,2);
6987 
6988   mat0 = (*mat)[0];
6989   if (mat0 && mat0->ops->destroysubmatrices) {
6990     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6991   } else {
6992     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6993   }
6994   PetscFunctionReturn(0);
6995 }
6996 
6997 /*@C
6998    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6999 
7000    Collective on Mat
7001 
7002    Input Parameters:
7003 .  mat - the matrix
7004 
7005    Output Parameter:
7006 .  matstruct - the sequential matrix with the nonzero structure of mat
7007 
7008   Level: intermediate
7009 
7010 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7011 @*/
7012 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7013 {
7014   PetscErrorCode ierr;
7015 
7016   PetscFunctionBegin;
7017   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7018   PetscValidPointer(matstruct,2);
7019 
7020   PetscValidType(mat,1);
7021   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7022   MatCheckPreallocated(mat,1);
7023 
7024   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7025   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7026   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7027   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7028   PetscFunctionReturn(0);
7029 }
7030 
7031 /*@C
7032    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7033 
7034    Collective on Mat
7035 
7036    Input Parameters:
7037 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7038                        sequence of MatGetSequentialNonzeroStructure())
7039 
7040    Level: advanced
7041 
7042     Notes:
7043     Frees not only the matrices, but also the array that contains the matrices
7044 
7045 .seealso: MatGetSeqNonzeroStructure()
7046 @*/
7047 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7048 {
7049   PetscErrorCode ierr;
7050 
7051   PetscFunctionBegin;
7052   PetscValidPointer(mat,1);
7053   ierr = MatDestroy(mat);CHKERRQ(ierr);
7054   PetscFunctionReturn(0);
7055 }
7056 
7057 /*@
7058    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7059    replaces the index sets by larger ones that represent submatrices with
7060    additional overlap.
7061 
7062    Collective on Mat
7063 
7064    Input Parameters:
7065 +  mat - the matrix
7066 .  n   - the number of index sets
7067 .  is  - the array of index sets (these index sets will changed during the call)
7068 -  ov  - the additional overlap requested
7069 
7070    Options Database:
7071 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7072 
7073    Level: developer
7074 
7075    Concepts: overlap
7076    Concepts: ASM^computing overlap
7077 
7078 .seealso: MatCreateSubMatrices()
7079 @*/
7080 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7081 {
7082   PetscErrorCode ierr;
7083 
7084   PetscFunctionBegin;
7085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7086   PetscValidType(mat,1);
7087   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7088   if (n) {
7089     PetscValidPointer(is,3);
7090     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7091   }
7092   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7093   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7094   MatCheckPreallocated(mat,1);
7095 
7096   if (!ov) PetscFunctionReturn(0);
7097   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7098   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7099   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7100   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7101   PetscFunctionReturn(0);
7102 }
7103 
7104 
7105 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7106 
7107 /*@
7108    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7109    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7110    additional overlap.
7111 
7112    Collective on Mat
7113 
7114    Input Parameters:
7115 +  mat - the matrix
7116 .  n   - the number of index sets
7117 .  is  - the array of index sets (these index sets will changed during the call)
7118 -  ov  - the additional overlap requested
7119 
7120    Options Database:
7121 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7122 
7123    Level: developer
7124 
7125    Concepts: overlap
7126    Concepts: ASM^computing overlap
7127 
7128 .seealso: MatCreateSubMatrices()
7129 @*/
7130 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7131 {
7132   PetscInt       i;
7133   PetscErrorCode ierr;
7134 
7135   PetscFunctionBegin;
7136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7137   PetscValidType(mat,1);
7138   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7139   if (n) {
7140     PetscValidPointer(is,3);
7141     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7142   }
7143   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7144   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7145   MatCheckPreallocated(mat,1);
7146   if (!ov) PetscFunctionReturn(0);
7147   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7148   for(i=0; i<n; i++){
7149 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7150   }
7151   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7152   PetscFunctionReturn(0);
7153 }
7154 
7155 
7156 
7157 
7158 /*@
7159    MatGetBlockSize - Returns the matrix block size.
7160 
7161    Not Collective
7162 
7163    Input Parameter:
7164 .  mat - the matrix
7165 
7166    Output Parameter:
7167 .  bs - block size
7168 
7169    Notes:
7170     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7171 
7172    If the block size has not been set yet this routine returns 1.
7173 
7174    Level: intermediate
7175 
7176    Concepts: matrices^block size
7177 
7178 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7179 @*/
7180 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7181 {
7182   PetscFunctionBegin;
7183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7184   PetscValidIntPointer(bs,2);
7185   *bs = PetscAbs(mat->rmap->bs);
7186   PetscFunctionReturn(0);
7187 }
7188 
7189 /*@
7190    MatGetBlockSizes - Returns the matrix block row and column sizes.
7191 
7192    Not Collective
7193 
7194    Input Parameter:
7195 .  mat - the matrix
7196 
7197    Output Parameter:
7198 .  rbs - row block size
7199 .  cbs - column block size
7200 
7201    Notes:
7202     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7203     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7204 
7205    If a block size has not been set yet this routine returns 1.
7206 
7207    Level: intermediate
7208 
7209    Concepts: matrices^block size
7210 
7211 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7212 @*/
7213 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7214 {
7215   PetscFunctionBegin;
7216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7217   if (rbs) PetscValidIntPointer(rbs,2);
7218   if (cbs) PetscValidIntPointer(cbs,3);
7219   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7220   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7221   PetscFunctionReturn(0);
7222 }
7223 
7224 /*@
7225    MatSetBlockSize - Sets the matrix block size.
7226 
7227    Logically Collective on Mat
7228 
7229    Input Parameters:
7230 +  mat - the matrix
7231 -  bs - block size
7232 
7233    Notes:
7234     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7235     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7236 
7237     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7238     is compatible with the matrix local sizes.
7239 
7240    Level: intermediate
7241 
7242    Concepts: matrices^block size
7243 
7244 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7245 @*/
7246 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7247 {
7248   PetscErrorCode ierr;
7249 
7250   PetscFunctionBegin;
7251   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7252   PetscValidLogicalCollectiveInt(mat,bs,2);
7253   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7254   PetscFunctionReturn(0);
7255 }
7256 
7257 /*@
7258    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7259 
7260    Logically Collective on Mat
7261 
7262    Input Parameters:
7263 +  mat - the matrix
7264 .  nblocks - the number of blocks on this process
7265 -  bsizes - the block sizes
7266 
7267    Notes:
7268     Currently used by PCVPBJACOBI for SeqAIJ matrices
7269 
7270    Level: intermediate
7271 
7272    Concepts: matrices^block size
7273 
7274 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7275 @*/
7276 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7277 {
7278   PetscErrorCode ierr;
7279   PetscInt       i,ncnt = 0, nlocal;
7280 
7281   PetscFunctionBegin;
7282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7283   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7284   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7285   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7286   if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7287   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7288   mat->nblocks = nblocks;
7289   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7290   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7291   PetscFunctionReturn(0);
7292 }
7293 
7294 /*@C
7295    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7296 
7297    Logically Collective on Mat
7298 
7299    Input Parameters:
7300 .  mat - the matrix
7301 
7302    Output Parameters:
7303 +  nblocks - the number of blocks on this process
7304 -  bsizes - the block sizes
7305 
7306    Notes: Currently not supported from Fortran
7307 
7308    Level: intermediate
7309 
7310    Concepts: matrices^block size
7311 
7312 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7313 @*/
7314 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7315 {
7316   PetscFunctionBegin;
7317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7318   *nblocks = mat->nblocks;
7319   *bsizes  = mat->bsizes;
7320   PetscFunctionReturn(0);
7321 }
7322 
7323 /*@
7324    MatSetBlockSizes - Sets the matrix block row and column sizes.
7325 
7326    Logically Collective on Mat
7327 
7328    Input Parameters:
7329 +  mat - the matrix
7330 -  rbs - row block size
7331 -  cbs - column block size
7332 
7333    Notes:
7334     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7335     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7336     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7337 
7338     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7339     are compatible with the matrix local sizes.
7340 
7341     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7342 
7343    Level: intermediate
7344 
7345    Concepts: matrices^block size
7346 
7347 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7348 @*/
7349 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7350 {
7351   PetscErrorCode ierr;
7352 
7353   PetscFunctionBegin;
7354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7355   PetscValidLogicalCollectiveInt(mat,rbs,2);
7356   PetscValidLogicalCollectiveInt(mat,cbs,3);
7357   if (mat->ops->setblocksizes) {
7358     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7359   }
7360   if (mat->rmap->refcnt) {
7361     ISLocalToGlobalMapping l2g = NULL;
7362     PetscLayout            nmap = NULL;
7363 
7364     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7365     if (mat->rmap->mapping) {
7366       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7367     }
7368     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7369     mat->rmap = nmap;
7370     mat->rmap->mapping = l2g;
7371   }
7372   if (mat->cmap->refcnt) {
7373     ISLocalToGlobalMapping l2g = NULL;
7374     PetscLayout            nmap = NULL;
7375 
7376     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7377     if (mat->cmap->mapping) {
7378       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7379     }
7380     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7381     mat->cmap = nmap;
7382     mat->cmap->mapping = l2g;
7383   }
7384   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7385   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7386   PetscFunctionReturn(0);
7387 }
7388 
7389 /*@
7390    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7391 
7392    Logically Collective on Mat
7393 
7394    Input Parameters:
7395 +  mat - the matrix
7396 .  fromRow - matrix from which to copy row block size
7397 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7398 
7399    Level: developer
7400 
7401    Concepts: matrices^block size
7402 
7403 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7404 @*/
7405 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7406 {
7407   PetscErrorCode ierr;
7408 
7409   PetscFunctionBegin;
7410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7411   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7412   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7413   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7414   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7415   PetscFunctionReturn(0);
7416 }
7417 
7418 /*@
7419    MatResidual - Default routine to calculate the residual.
7420 
7421    Collective on Mat and Vec
7422 
7423    Input Parameters:
7424 +  mat - the matrix
7425 .  b   - the right-hand-side
7426 -  x   - the approximate solution
7427 
7428    Output Parameter:
7429 .  r - location to store the residual
7430 
7431    Level: developer
7432 
7433 .keywords: MG, default, multigrid, residual
7434 
7435 .seealso: PCMGSetResidual()
7436 @*/
7437 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7438 {
7439   PetscErrorCode ierr;
7440 
7441   PetscFunctionBegin;
7442   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7443   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7444   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7445   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7446   PetscValidType(mat,1);
7447   MatCheckPreallocated(mat,1);
7448   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7449   if (!mat->ops->residual) {
7450     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7451     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7452   } else {
7453     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7454   }
7455   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7456   PetscFunctionReturn(0);
7457 }
7458 
7459 /*@C
7460     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7461 
7462    Collective on Mat
7463 
7464     Input Parameters:
7465 +   mat - the matrix
7466 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7467 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7468 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7469                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7470                  always used.
7471 
7472     Output Parameters:
7473 +   n - number of rows in the (possibly compressed) matrix
7474 .   ia - the row pointers [of length n+1]
7475 .   ja - the column indices
7476 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7477            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7478 
7479     Level: developer
7480 
7481     Notes:
7482     You CANNOT change any of the ia[] or ja[] values.
7483 
7484     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7485 
7486     Fortran Notes:
7487     In Fortran use
7488 $
7489 $      PetscInt ia(1), ja(1)
7490 $      PetscOffset iia, jja
7491 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7492 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7493 
7494      or
7495 $
7496 $    PetscInt, pointer :: ia(:),ja(:)
7497 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7498 $    ! Access the ith and jth entries via ia(i) and ja(j)
7499 
7500 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7501 @*/
7502 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7503 {
7504   PetscErrorCode ierr;
7505 
7506   PetscFunctionBegin;
7507   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7508   PetscValidType(mat,1);
7509   PetscValidIntPointer(n,5);
7510   if (ia) PetscValidIntPointer(ia,6);
7511   if (ja) PetscValidIntPointer(ja,7);
7512   PetscValidIntPointer(done,8);
7513   MatCheckPreallocated(mat,1);
7514   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7515   else {
7516     *done = PETSC_TRUE;
7517     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7518     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7519     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7520   }
7521   PetscFunctionReturn(0);
7522 }
7523 
7524 /*@C
7525     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7526 
7527     Collective on Mat
7528 
7529     Input Parameters:
7530 +   mat - the matrix
7531 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7532 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7533                 symmetrized
7534 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7535                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7536                  always used.
7537 .   n - number of columns in the (possibly compressed) matrix
7538 .   ia - the column pointers
7539 -   ja - the row indices
7540 
7541     Output Parameters:
7542 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7543 
7544     Note:
7545     This routine zeros out n, ia, and ja. This is to prevent accidental
7546     us of the array after it has been restored. If you pass NULL, it will
7547     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7548 
7549     Level: developer
7550 
7551 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7552 @*/
7553 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7554 {
7555   PetscErrorCode ierr;
7556 
7557   PetscFunctionBegin;
7558   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7559   PetscValidType(mat,1);
7560   PetscValidIntPointer(n,4);
7561   if (ia) PetscValidIntPointer(ia,5);
7562   if (ja) PetscValidIntPointer(ja,6);
7563   PetscValidIntPointer(done,7);
7564   MatCheckPreallocated(mat,1);
7565   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7566   else {
7567     *done = PETSC_TRUE;
7568     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7569   }
7570   PetscFunctionReturn(0);
7571 }
7572 
7573 /*@C
7574     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7575     MatGetRowIJ().
7576 
7577     Collective on Mat
7578 
7579     Input Parameters:
7580 +   mat - the matrix
7581 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7582 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7583                 symmetrized
7584 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7585                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7586                  always used.
7587 .   n - size of (possibly compressed) matrix
7588 .   ia - the row pointers
7589 -   ja - the column indices
7590 
7591     Output Parameters:
7592 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7593 
7594     Note:
7595     This routine zeros out n, ia, and ja. This is to prevent accidental
7596     us of the array after it has been restored. If you pass NULL, it will
7597     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7598 
7599     Level: developer
7600 
7601 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7602 @*/
7603 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7604 {
7605   PetscErrorCode ierr;
7606 
7607   PetscFunctionBegin;
7608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7609   PetscValidType(mat,1);
7610   if (ia) PetscValidIntPointer(ia,6);
7611   if (ja) PetscValidIntPointer(ja,7);
7612   PetscValidIntPointer(done,8);
7613   MatCheckPreallocated(mat,1);
7614 
7615   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7616   else {
7617     *done = PETSC_TRUE;
7618     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7619     if (n)  *n = 0;
7620     if (ia) *ia = NULL;
7621     if (ja) *ja = NULL;
7622   }
7623   PetscFunctionReturn(0);
7624 }
7625 
7626 /*@C
7627     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7628     MatGetColumnIJ().
7629 
7630     Collective on Mat
7631 
7632     Input Parameters:
7633 +   mat - the matrix
7634 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7635 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7636                 symmetrized
7637 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7638                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7639                  always used.
7640 
7641     Output Parameters:
7642 +   n - size of (possibly compressed) matrix
7643 .   ia - the column pointers
7644 .   ja - the row indices
7645 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7646 
7647     Level: developer
7648 
7649 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7650 @*/
7651 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7652 {
7653   PetscErrorCode ierr;
7654 
7655   PetscFunctionBegin;
7656   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7657   PetscValidType(mat,1);
7658   if (ia) PetscValidIntPointer(ia,5);
7659   if (ja) PetscValidIntPointer(ja,6);
7660   PetscValidIntPointer(done,7);
7661   MatCheckPreallocated(mat,1);
7662 
7663   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7664   else {
7665     *done = PETSC_TRUE;
7666     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7667     if (n)  *n = 0;
7668     if (ia) *ia = NULL;
7669     if (ja) *ja = NULL;
7670   }
7671   PetscFunctionReturn(0);
7672 }
7673 
7674 /*@C
7675     MatColoringPatch -Used inside matrix coloring routines that
7676     use MatGetRowIJ() and/or MatGetColumnIJ().
7677 
7678     Collective on Mat
7679 
7680     Input Parameters:
7681 +   mat - the matrix
7682 .   ncolors - max color value
7683 .   n   - number of entries in colorarray
7684 -   colorarray - array indicating color for each column
7685 
7686     Output Parameters:
7687 .   iscoloring - coloring generated using colorarray information
7688 
7689     Level: developer
7690 
7691 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7692 
7693 @*/
7694 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7695 {
7696   PetscErrorCode ierr;
7697 
7698   PetscFunctionBegin;
7699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7700   PetscValidType(mat,1);
7701   PetscValidIntPointer(colorarray,4);
7702   PetscValidPointer(iscoloring,5);
7703   MatCheckPreallocated(mat,1);
7704 
7705   if (!mat->ops->coloringpatch) {
7706     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7707   } else {
7708     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7709   }
7710   PetscFunctionReturn(0);
7711 }
7712 
7713 
7714 /*@
7715    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7716 
7717    Logically Collective on Mat
7718 
7719    Input Parameter:
7720 .  mat - the factored matrix to be reset
7721 
7722    Notes:
7723    This routine should be used only with factored matrices formed by in-place
7724    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7725    format).  This option can save memory, for example, when solving nonlinear
7726    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7727    ILU(0) preconditioner.
7728 
7729    Note that one can specify in-place ILU(0) factorization by calling
7730 .vb
7731      PCType(pc,PCILU);
7732      PCFactorSeUseInPlace(pc);
7733 .ve
7734    or by using the options -pc_type ilu -pc_factor_in_place
7735 
7736    In-place factorization ILU(0) can also be used as a local
7737    solver for the blocks within the block Jacobi or additive Schwarz
7738    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7739    for details on setting local solver options.
7740 
7741    Most users should employ the simplified KSP interface for linear solvers
7742    instead of working directly with matrix algebra routines such as this.
7743    See, e.g., KSPCreate().
7744 
7745    Level: developer
7746 
7747 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7748 
7749    Concepts: matrices^unfactored
7750 
7751 @*/
7752 PetscErrorCode MatSetUnfactored(Mat mat)
7753 {
7754   PetscErrorCode ierr;
7755 
7756   PetscFunctionBegin;
7757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7758   PetscValidType(mat,1);
7759   MatCheckPreallocated(mat,1);
7760   mat->factortype = MAT_FACTOR_NONE;
7761   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7762   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7763   PetscFunctionReturn(0);
7764 }
7765 
7766 /*MC
7767     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7768 
7769     Synopsis:
7770     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7771 
7772     Not collective
7773 
7774     Input Parameter:
7775 .   x - matrix
7776 
7777     Output Parameters:
7778 +   xx_v - the Fortran90 pointer to the array
7779 -   ierr - error code
7780 
7781     Example of Usage:
7782 .vb
7783       PetscScalar, pointer xx_v(:,:)
7784       ....
7785       call MatDenseGetArrayF90(x,xx_v,ierr)
7786       a = xx_v(3)
7787       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7788 .ve
7789 
7790     Level: advanced
7791 
7792 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7793 
7794     Concepts: matrices^accessing array
7795 
7796 M*/
7797 
7798 /*MC
7799     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7800     accessed with MatDenseGetArrayF90().
7801 
7802     Synopsis:
7803     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7804 
7805     Not collective
7806 
7807     Input Parameters:
7808 +   x - matrix
7809 -   xx_v - the Fortran90 pointer to the array
7810 
7811     Output Parameter:
7812 .   ierr - error code
7813 
7814     Example of Usage:
7815 .vb
7816        PetscScalar, pointer xx_v(:,:)
7817        ....
7818        call MatDenseGetArrayF90(x,xx_v,ierr)
7819        a = xx_v(3)
7820        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7821 .ve
7822 
7823     Level: advanced
7824 
7825 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7826 
7827 M*/
7828 
7829 
7830 /*MC
7831     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7832 
7833     Synopsis:
7834     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7835 
7836     Not collective
7837 
7838     Input Parameter:
7839 .   x - matrix
7840 
7841     Output Parameters:
7842 +   xx_v - the Fortran90 pointer to the array
7843 -   ierr - error code
7844 
7845     Example of Usage:
7846 .vb
7847       PetscScalar, pointer xx_v(:)
7848       ....
7849       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7850       a = xx_v(3)
7851       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7852 .ve
7853 
7854     Level: advanced
7855 
7856 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7857 
7858     Concepts: matrices^accessing array
7859 
7860 M*/
7861 
7862 /*MC
7863     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7864     accessed with MatSeqAIJGetArrayF90().
7865 
7866     Synopsis:
7867     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7868 
7869     Not collective
7870 
7871     Input Parameters:
7872 +   x - matrix
7873 -   xx_v - the Fortran90 pointer to the array
7874 
7875     Output Parameter:
7876 .   ierr - error code
7877 
7878     Example of Usage:
7879 .vb
7880        PetscScalar, pointer xx_v(:)
7881        ....
7882        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7883        a = xx_v(3)
7884        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7885 .ve
7886 
7887     Level: advanced
7888 
7889 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7890 
7891 M*/
7892 
7893 
7894 /*@
7895     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7896                       as the original matrix.
7897 
7898     Collective on Mat
7899 
7900     Input Parameters:
7901 +   mat - the original matrix
7902 .   isrow - parallel IS containing the rows this processor should obtain
7903 .   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.
7904 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7905 
7906     Output Parameter:
7907 .   newmat - the new submatrix, of the same type as the old
7908 
7909     Level: advanced
7910 
7911     Notes:
7912     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7913 
7914     Some matrix types place restrictions on the row and column indices, such
7915     as that they be sorted or that they be equal to each other.
7916 
7917     The index sets may not have duplicate entries.
7918 
7919       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7920    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7921    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7922    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7923    you are finished using it.
7924 
7925     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7926     the input matrix.
7927 
7928     If iscol is NULL then all columns are obtained (not supported in Fortran).
7929 
7930    Example usage:
7931    Consider the following 8x8 matrix with 34 non-zero values, that is
7932    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7933    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7934    as follows:
7935 
7936 .vb
7937             1  2  0  |  0  3  0  |  0  4
7938     Proc0   0  5  6  |  7  0  0  |  8  0
7939             9  0 10  | 11  0  0  | 12  0
7940     -------------------------------------
7941            13  0 14  | 15 16 17  |  0  0
7942     Proc1   0 18  0  | 19 20 21  |  0  0
7943             0  0  0  | 22 23  0  | 24  0
7944     -------------------------------------
7945     Proc2  25 26 27  |  0  0 28  | 29  0
7946            30  0  0  | 31 32 33  |  0 34
7947 .ve
7948 
7949     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7950 
7951 .vb
7952             2  0  |  0  3  0  |  0
7953     Proc0   5  6  |  7  0  0  |  8
7954     -------------------------------
7955     Proc1  18  0  | 19 20 21  |  0
7956     -------------------------------
7957     Proc2  26 27  |  0  0 28  | 29
7958             0  0  | 31 32 33  |  0
7959 .ve
7960 
7961 
7962     Concepts: matrices^submatrices
7963 
7964 .seealso: MatCreateSubMatrices()
7965 @*/
7966 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7967 {
7968   PetscErrorCode ierr;
7969   PetscMPIInt    size;
7970   Mat            *local;
7971   IS             iscoltmp;
7972 
7973   PetscFunctionBegin;
7974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7975   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7976   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7977   PetscValidPointer(newmat,5);
7978   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7979   PetscValidType(mat,1);
7980   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7981   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7982 
7983   MatCheckPreallocated(mat,1);
7984   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7985 
7986   if (!iscol || isrow == iscol) {
7987     PetscBool   stride;
7988     PetscMPIInt grabentirematrix = 0,grab;
7989     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7990     if (stride) {
7991       PetscInt first,step,n,rstart,rend;
7992       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7993       if (step == 1) {
7994         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7995         if (rstart == first) {
7996           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7997           if (n == rend-rstart) {
7998             grabentirematrix = 1;
7999           }
8000         }
8001       }
8002     }
8003     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8004     if (grab) {
8005       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8006       if (cll == MAT_INITIAL_MATRIX) {
8007         *newmat = mat;
8008         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8009       }
8010       PetscFunctionReturn(0);
8011     }
8012   }
8013 
8014   if (!iscol) {
8015     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8016   } else {
8017     iscoltmp = iscol;
8018   }
8019 
8020   /* if original matrix is on just one processor then use submatrix generated */
8021   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8022     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8023     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8024     PetscFunctionReturn(0);
8025   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8026     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8027     *newmat = *local;
8028     ierr    = PetscFree(local);CHKERRQ(ierr);
8029     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8030     PetscFunctionReturn(0);
8031   } else if (!mat->ops->createsubmatrix) {
8032     /* Create a new matrix type that implements the operation using the full matrix */
8033     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8034     switch (cll) {
8035     case MAT_INITIAL_MATRIX:
8036       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8037       break;
8038     case MAT_REUSE_MATRIX:
8039       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8040       break;
8041     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8042     }
8043     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8044     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8045     PetscFunctionReturn(0);
8046   }
8047 
8048   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8049   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8050   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8051   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8052 
8053   /* Propagate symmetry information for diagonal blocks */
8054   if (isrow == iscoltmp) {
8055     if (mat->symmetric_set && mat->symmetric) {
8056       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8057     }
8058     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8059       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8060     }
8061     if (mat->hermitian_set && mat->hermitian) {
8062       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8063     }
8064     if (mat->spd_set && mat->spd) {
8065       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8066     }
8067   }
8068 
8069   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8070   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8071   PetscFunctionReturn(0);
8072 }
8073 
8074 /*@
8075    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8076    used during the assembly process to store values that belong to
8077    other processors.
8078 
8079    Not Collective
8080 
8081    Input Parameters:
8082 +  mat   - the matrix
8083 .  size  - the initial size of the stash.
8084 -  bsize - the initial size of the block-stash(if used).
8085 
8086    Options Database Keys:
8087 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8088 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8089 
8090    Level: intermediate
8091 
8092    Notes:
8093      The block-stash is used for values set with MatSetValuesBlocked() while
8094      the stash is used for values set with MatSetValues()
8095 
8096      Run with the option -info and look for output of the form
8097      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8098      to determine the appropriate value, MM, to use for size and
8099      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8100      to determine the value, BMM to use for bsize
8101 
8102    Concepts: stash^setting matrix size
8103    Concepts: matrices^stash
8104 
8105 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8106 
8107 @*/
8108 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8109 {
8110   PetscErrorCode ierr;
8111 
8112   PetscFunctionBegin;
8113   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8114   PetscValidType(mat,1);
8115   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8116   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8117   PetscFunctionReturn(0);
8118 }
8119 
8120 /*@
8121    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8122      the matrix
8123 
8124    Neighbor-wise Collective on Mat
8125 
8126    Input Parameters:
8127 +  mat   - the matrix
8128 .  x,y - the vectors
8129 -  w - where the result is stored
8130 
8131    Level: intermediate
8132 
8133    Notes:
8134     w may be the same vector as y.
8135 
8136     This allows one to use either the restriction or interpolation (its transpose)
8137     matrix to do the interpolation
8138 
8139     Concepts: interpolation
8140 
8141 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8142 
8143 @*/
8144 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8145 {
8146   PetscErrorCode ierr;
8147   PetscInt       M,N,Ny;
8148 
8149   PetscFunctionBegin;
8150   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8151   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8152   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8153   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8154   PetscValidType(A,1);
8155   MatCheckPreallocated(A,1);
8156   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8157   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8158   if (M == Ny) {
8159     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8160   } else {
8161     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8162   }
8163   PetscFunctionReturn(0);
8164 }
8165 
8166 /*@
8167    MatInterpolate - y = A*x or A'*x depending on the shape of
8168      the matrix
8169 
8170    Neighbor-wise Collective on Mat
8171 
8172    Input Parameters:
8173 +  mat   - the matrix
8174 -  x,y - the vectors
8175 
8176    Level: intermediate
8177 
8178    Notes:
8179     This allows one to use either the restriction or interpolation (its transpose)
8180     matrix to do the interpolation
8181 
8182    Concepts: matrices^interpolation
8183 
8184 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8185 
8186 @*/
8187 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8188 {
8189   PetscErrorCode ierr;
8190   PetscInt       M,N,Ny;
8191 
8192   PetscFunctionBegin;
8193   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8194   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8195   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8196   PetscValidType(A,1);
8197   MatCheckPreallocated(A,1);
8198   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8199   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8200   if (M == Ny) {
8201     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8202   } else {
8203     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8204   }
8205   PetscFunctionReturn(0);
8206 }
8207 
8208 /*@
8209    MatRestrict - y = A*x or A'*x
8210 
8211    Neighbor-wise Collective on Mat
8212 
8213    Input Parameters:
8214 +  mat   - the matrix
8215 -  x,y - the vectors
8216 
8217    Level: intermediate
8218 
8219    Notes:
8220     This allows one to use either the restriction or interpolation (its transpose)
8221     matrix to do the restriction
8222 
8223    Concepts: matrices^restriction
8224 
8225 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8226 
8227 @*/
8228 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8229 {
8230   PetscErrorCode ierr;
8231   PetscInt       M,N,Ny;
8232 
8233   PetscFunctionBegin;
8234   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8235   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8236   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8237   PetscValidType(A,1);
8238   MatCheckPreallocated(A,1);
8239 
8240   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8241   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8242   if (M == Ny) {
8243     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8244   } else {
8245     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8246   }
8247   PetscFunctionReturn(0);
8248 }
8249 
8250 /*@
8251    MatGetNullSpace - retrieves the null space of a matrix.
8252 
8253    Logically Collective on Mat and MatNullSpace
8254 
8255    Input Parameters:
8256 +  mat - the matrix
8257 -  nullsp - the null space object
8258 
8259    Level: developer
8260 
8261    Concepts: null space^attaching to matrix
8262 
8263 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8264 @*/
8265 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8266 {
8267   PetscFunctionBegin;
8268   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8269   PetscValidPointer(nullsp,2);
8270   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8271   PetscFunctionReturn(0);
8272 }
8273 
8274 /*@
8275    MatSetNullSpace - attaches a null space to a matrix.
8276 
8277    Logically Collective on Mat and MatNullSpace
8278 
8279    Input Parameters:
8280 +  mat - the matrix
8281 -  nullsp - the null space object
8282 
8283    Level: advanced
8284 
8285    Notes:
8286       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8287 
8288       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8289       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8290 
8291       You can remove the null space by calling this routine with an nullsp of NULL
8292 
8293 
8294       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8295    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).
8296    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
8297    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
8298    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).
8299 
8300       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8301 
8302     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
8303     routine also automatically calls MatSetTransposeNullSpace().
8304 
8305    Concepts: null space^attaching to matrix
8306 
8307 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8308 @*/
8309 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8310 {
8311   PetscErrorCode ierr;
8312 
8313   PetscFunctionBegin;
8314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8315   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8316   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8317   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8318   mat->nullsp = nullsp;
8319   if (mat->symmetric_set && mat->symmetric) {
8320     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8321   }
8322   PetscFunctionReturn(0);
8323 }
8324 
8325 /*@
8326    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8327 
8328    Logically Collective on Mat and MatNullSpace
8329 
8330    Input Parameters:
8331 +  mat - the matrix
8332 -  nullsp - the null space object
8333 
8334    Level: developer
8335 
8336    Concepts: null space^attaching to matrix
8337 
8338 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8339 @*/
8340 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8341 {
8342   PetscFunctionBegin;
8343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8344   PetscValidType(mat,1);
8345   PetscValidPointer(nullsp,2);
8346   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8347   PetscFunctionReturn(0);
8348 }
8349 
8350 /*@
8351    MatSetTransposeNullSpace - attaches a null space to a matrix.
8352 
8353    Logically Collective on Mat and MatNullSpace
8354 
8355    Input Parameters:
8356 +  mat - the matrix
8357 -  nullsp - the null space object
8358 
8359    Level: advanced
8360 
8361    Notes:
8362       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.
8363       You must also call MatSetNullSpace()
8364 
8365 
8366       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8367    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).
8368    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
8369    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
8370    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).
8371 
8372       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8373 
8374    Concepts: null space^attaching to matrix
8375 
8376 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8377 @*/
8378 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8379 {
8380   PetscErrorCode ierr;
8381 
8382   PetscFunctionBegin;
8383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8384   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8385   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8386   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8387   mat->transnullsp = nullsp;
8388   PetscFunctionReturn(0);
8389 }
8390 
8391 /*@
8392    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8393         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8394 
8395    Logically Collective on Mat and MatNullSpace
8396 
8397    Input Parameters:
8398 +  mat - the matrix
8399 -  nullsp - the null space object
8400 
8401    Level: advanced
8402 
8403    Notes:
8404       Overwrites any previous near null space that may have been attached
8405 
8406       You can remove the null space by calling this routine with an nullsp of NULL
8407 
8408    Concepts: null space^attaching to matrix
8409 
8410 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8411 @*/
8412 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8413 {
8414   PetscErrorCode ierr;
8415 
8416   PetscFunctionBegin;
8417   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8418   PetscValidType(mat,1);
8419   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8420   MatCheckPreallocated(mat,1);
8421   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8422   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8423   mat->nearnullsp = nullsp;
8424   PetscFunctionReturn(0);
8425 }
8426 
8427 /*@
8428    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8429 
8430    Not Collective
8431 
8432    Input Parameters:
8433 .  mat - the matrix
8434 
8435    Output Parameters:
8436 .  nullsp - the null space object, NULL if not set
8437 
8438    Level: developer
8439 
8440    Concepts: null space^attaching to matrix
8441 
8442 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8443 @*/
8444 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8445 {
8446   PetscFunctionBegin;
8447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8448   PetscValidType(mat,1);
8449   PetscValidPointer(nullsp,2);
8450   MatCheckPreallocated(mat,1);
8451   *nullsp = mat->nearnullsp;
8452   PetscFunctionReturn(0);
8453 }
8454 
8455 /*@C
8456    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8457 
8458    Collective on Mat
8459 
8460    Input Parameters:
8461 +  mat - the matrix
8462 .  row - row/column permutation
8463 .  fill - expected fill factor >= 1.0
8464 -  level - level of fill, for ICC(k)
8465 
8466    Notes:
8467    Probably really in-place only when level of fill is zero, otherwise allocates
8468    new space to store factored matrix and deletes previous memory.
8469 
8470    Most users should employ the simplified KSP interface for linear solvers
8471    instead of working directly with matrix algebra routines such as this.
8472    See, e.g., KSPCreate().
8473 
8474    Level: developer
8475 
8476    Concepts: matrices^incomplete Cholesky factorization
8477    Concepts: Cholesky factorization
8478 
8479 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8480 
8481     Developer Note: fortran interface is not autogenerated as the f90
8482     interface defintion cannot be generated correctly [due to MatFactorInfo]
8483 
8484 @*/
8485 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8486 {
8487   PetscErrorCode ierr;
8488 
8489   PetscFunctionBegin;
8490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8491   PetscValidType(mat,1);
8492   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8493   PetscValidPointer(info,3);
8494   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8495   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8496   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8497   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8498   MatCheckPreallocated(mat,1);
8499   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8500   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8501   PetscFunctionReturn(0);
8502 }
8503 
8504 /*@
8505    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8506          ghosted ones.
8507 
8508    Not Collective
8509 
8510    Input Parameters:
8511 +  mat - the matrix
8512 -  diag = the diagonal values, including ghost ones
8513 
8514    Level: developer
8515 
8516    Notes:
8517     Works only for MPIAIJ and MPIBAIJ matrices
8518 
8519 .seealso: MatDiagonalScale()
8520 @*/
8521 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8522 {
8523   PetscErrorCode ierr;
8524   PetscMPIInt    size;
8525 
8526   PetscFunctionBegin;
8527   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8528   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8529   PetscValidType(mat,1);
8530 
8531   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8532   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8533   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8534   if (size == 1) {
8535     PetscInt n,m;
8536     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8537     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8538     if (m == n) {
8539       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8540     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8541   } else {
8542     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8543   }
8544   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8545   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8546   PetscFunctionReturn(0);
8547 }
8548 
8549 /*@
8550    MatGetInertia - Gets the inertia from a factored matrix
8551 
8552    Collective on Mat
8553 
8554    Input Parameter:
8555 .  mat - the matrix
8556 
8557    Output Parameters:
8558 +   nneg - number of negative eigenvalues
8559 .   nzero - number of zero eigenvalues
8560 -   npos - number of positive eigenvalues
8561 
8562    Level: advanced
8563 
8564    Notes:
8565     Matrix must have been factored by MatCholeskyFactor()
8566 
8567 
8568 @*/
8569 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8570 {
8571   PetscErrorCode ierr;
8572 
8573   PetscFunctionBegin;
8574   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8575   PetscValidType(mat,1);
8576   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8577   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8578   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8579   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8580   PetscFunctionReturn(0);
8581 }
8582 
8583 /* ----------------------------------------------------------------*/
8584 /*@C
8585    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8586 
8587    Neighbor-wise Collective on Mat and Vecs
8588 
8589    Input Parameters:
8590 +  mat - the factored matrix
8591 -  b - the right-hand-side vectors
8592 
8593    Output Parameter:
8594 .  x - the result vectors
8595 
8596    Notes:
8597    The vectors b and x cannot be the same.  I.e., one cannot
8598    call MatSolves(A,x,x).
8599 
8600    Notes:
8601    Most users should employ the simplified KSP interface for linear solvers
8602    instead of working directly with matrix algebra routines such as this.
8603    See, e.g., KSPCreate().
8604 
8605    Level: developer
8606 
8607    Concepts: matrices^triangular solves
8608 
8609 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8610 @*/
8611 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8612 {
8613   PetscErrorCode ierr;
8614 
8615   PetscFunctionBegin;
8616   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8617   PetscValidType(mat,1);
8618   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8619   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8620   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8621 
8622   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8623   MatCheckPreallocated(mat,1);
8624   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8625   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8626   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8627   PetscFunctionReturn(0);
8628 }
8629 
8630 /*@
8631    MatIsSymmetric - Test whether a matrix is symmetric
8632 
8633    Collective on Mat
8634 
8635    Input Parameter:
8636 +  A - the matrix to test
8637 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8638 
8639    Output Parameters:
8640 .  flg - the result
8641 
8642    Notes:
8643     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8644 
8645    Level: intermediate
8646 
8647    Concepts: matrix^symmetry
8648 
8649 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8650 @*/
8651 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8652 {
8653   PetscErrorCode ierr;
8654 
8655   PetscFunctionBegin;
8656   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8657   PetscValidPointer(flg,2);
8658 
8659   if (!A->symmetric_set) {
8660     if (!A->ops->issymmetric) {
8661       MatType mattype;
8662       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8663       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8664     }
8665     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8666     if (!tol) {
8667       A->symmetric_set = PETSC_TRUE;
8668       A->symmetric     = *flg;
8669       if (A->symmetric) {
8670         A->structurally_symmetric_set = PETSC_TRUE;
8671         A->structurally_symmetric     = PETSC_TRUE;
8672       }
8673     }
8674   } else if (A->symmetric) {
8675     *flg = PETSC_TRUE;
8676   } else if (!tol) {
8677     *flg = PETSC_FALSE;
8678   } else {
8679     if (!A->ops->issymmetric) {
8680       MatType mattype;
8681       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8682       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8683     }
8684     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8685   }
8686   PetscFunctionReturn(0);
8687 }
8688 
8689 /*@
8690    MatIsHermitian - Test whether a matrix is Hermitian
8691 
8692    Collective on Mat
8693 
8694    Input Parameter:
8695 +  A - the matrix to test
8696 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8697 
8698    Output Parameters:
8699 .  flg - the result
8700 
8701    Level: intermediate
8702 
8703    Concepts: matrix^symmetry
8704 
8705 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8706           MatIsSymmetricKnown(), MatIsSymmetric()
8707 @*/
8708 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8709 {
8710   PetscErrorCode ierr;
8711 
8712   PetscFunctionBegin;
8713   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8714   PetscValidPointer(flg,2);
8715 
8716   if (!A->hermitian_set) {
8717     if (!A->ops->ishermitian) {
8718       MatType mattype;
8719       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8720       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8721     }
8722     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8723     if (!tol) {
8724       A->hermitian_set = PETSC_TRUE;
8725       A->hermitian     = *flg;
8726       if (A->hermitian) {
8727         A->structurally_symmetric_set = PETSC_TRUE;
8728         A->structurally_symmetric     = PETSC_TRUE;
8729       }
8730     }
8731   } else if (A->hermitian) {
8732     *flg = PETSC_TRUE;
8733   } else if (!tol) {
8734     *flg = PETSC_FALSE;
8735   } else {
8736     if (!A->ops->ishermitian) {
8737       MatType mattype;
8738       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8739       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8740     }
8741     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8742   }
8743   PetscFunctionReturn(0);
8744 }
8745 
8746 /*@
8747    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8748 
8749    Not Collective
8750 
8751    Input Parameter:
8752 .  A - the matrix to check
8753 
8754    Output Parameters:
8755 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8756 -  flg - the result
8757 
8758    Level: advanced
8759 
8760    Concepts: matrix^symmetry
8761 
8762    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8763          if you want it explicitly checked
8764 
8765 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8766 @*/
8767 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8768 {
8769   PetscFunctionBegin;
8770   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8771   PetscValidPointer(set,2);
8772   PetscValidPointer(flg,3);
8773   if (A->symmetric_set) {
8774     *set = PETSC_TRUE;
8775     *flg = A->symmetric;
8776   } else {
8777     *set = PETSC_FALSE;
8778   }
8779   PetscFunctionReturn(0);
8780 }
8781 
8782 /*@
8783    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8784 
8785    Not Collective
8786 
8787    Input Parameter:
8788 .  A - the matrix to check
8789 
8790    Output Parameters:
8791 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8792 -  flg - the result
8793 
8794    Level: advanced
8795 
8796    Concepts: matrix^symmetry
8797 
8798    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8799          if you want it explicitly checked
8800 
8801 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8802 @*/
8803 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8804 {
8805   PetscFunctionBegin;
8806   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8807   PetscValidPointer(set,2);
8808   PetscValidPointer(flg,3);
8809   if (A->hermitian_set) {
8810     *set = PETSC_TRUE;
8811     *flg = A->hermitian;
8812   } else {
8813     *set = PETSC_FALSE;
8814   }
8815   PetscFunctionReturn(0);
8816 }
8817 
8818 /*@
8819    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8820 
8821    Collective on Mat
8822 
8823    Input Parameter:
8824 .  A - the matrix to test
8825 
8826    Output Parameters:
8827 .  flg - the result
8828 
8829    Level: intermediate
8830 
8831    Concepts: matrix^symmetry
8832 
8833 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8834 @*/
8835 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8836 {
8837   PetscErrorCode ierr;
8838 
8839   PetscFunctionBegin;
8840   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8841   PetscValidPointer(flg,2);
8842   if (!A->structurally_symmetric_set) {
8843     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8844     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8845 
8846     A->structurally_symmetric_set = PETSC_TRUE;
8847   }
8848   *flg = A->structurally_symmetric;
8849   PetscFunctionReturn(0);
8850 }
8851 
8852 /*@
8853    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8854        to be communicated to other processors during the MatAssemblyBegin/End() process
8855 
8856     Not collective
8857 
8858    Input Parameter:
8859 .   vec - the vector
8860 
8861    Output Parameters:
8862 +   nstash   - the size of the stash
8863 .   reallocs - the number of additional mallocs incurred.
8864 .   bnstash   - the size of the block stash
8865 -   breallocs - the number of additional mallocs incurred.in the block stash
8866 
8867    Level: advanced
8868 
8869 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8870 
8871 @*/
8872 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8873 {
8874   PetscErrorCode ierr;
8875 
8876   PetscFunctionBegin;
8877   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8878   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8879   PetscFunctionReturn(0);
8880 }
8881 
8882 /*@C
8883    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8884      parallel layout
8885 
8886    Collective on Mat
8887 
8888    Input Parameter:
8889 .  mat - the matrix
8890 
8891    Output Parameter:
8892 +   right - (optional) vector that the matrix can be multiplied against
8893 -   left - (optional) vector that the matrix vector product can be stored in
8894 
8895    Notes:
8896     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().
8897 
8898   Notes:
8899     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8900 
8901   Level: advanced
8902 
8903 .seealso: MatCreate(), VecDestroy()
8904 @*/
8905 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8906 {
8907   PetscErrorCode ierr;
8908 
8909   PetscFunctionBegin;
8910   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8911   PetscValidType(mat,1);
8912   if (mat->ops->getvecs) {
8913     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8914   } else {
8915     PetscInt rbs,cbs;
8916     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8917     if (right) {
8918       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8919       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8920       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8921       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8922       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8923       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8924     }
8925     if (left) {
8926       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8927       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8928       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8929       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8930       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8931       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8932     }
8933   }
8934   PetscFunctionReturn(0);
8935 }
8936 
8937 /*@C
8938    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8939      with default values.
8940 
8941    Not Collective
8942 
8943    Input Parameters:
8944 .    info - the MatFactorInfo data structure
8945 
8946 
8947    Notes:
8948     The solvers are generally used through the KSP and PC objects, for example
8949           PCLU, PCILU, PCCHOLESKY, PCICC
8950 
8951    Level: developer
8952 
8953 .seealso: MatFactorInfo
8954 
8955     Developer Note: fortran interface is not autogenerated as the f90
8956     interface defintion cannot be generated correctly [due to MatFactorInfo]
8957 
8958 @*/
8959 
8960 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8961 {
8962   PetscErrorCode ierr;
8963 
8964   PetscFunctionBegin;
8965   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8966   PetscFunctionReturn(0);
8967 }
8968 
8969 /*@
8970    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8971 
8972    Collective on Mat
8973 
8974    Input Parameters:
8975 +  mat - the factored matrix
8976 -  is - the index set defining the Schur indices (0-based)
8977 
8978    Notes:
8979     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8980 
8981    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8982 
8983    Level: developer
8984 
8985    Concepts:
8986 
8987 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8988           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8989 
8990 @*/
8991 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8992 {
8993   PetscErrorCode ierr,(*f)(Mat,IS);
8994 
8995   PetscFunctionBegin;
8996   PetscValidType(mat,1);
8997   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8998   PetscValidType(is,2);
8999   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9000   PetscCheckSameComm(mat,1,is,2);
9001   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9002   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9003   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");
9004   if (mat->schur) {
9005     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9006   }
9007   ierr = (*f)(mat,is);CHKERRQ(ierr);
9008   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9009   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9010   PetscFunctionReturn(0);
9011 }
9012 
9013 /*@
9014   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9015 
9016    Logically Collective on Mat
9017 
9018    Input Parameters:
9019 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9020 .  S - location where to return the Schur complement, can be NULL
9021 -  status - the status of the Schur complement matrix, can be NULL
9022 
9023    Notes:
9024    You must call MatFactorSetSchurIS() before calling this routine.
9025 
9026    The routine provides a copy of the Schur matrix stored within the solver data structures.
9027    The caller must destroy the object when it is no longer needed.
9028    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9029 
9030    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)
9031 
9032    Developer Notes:
9033     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9034    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9035 
9036    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9037 
9038    Level: advanced
9039 
9040    References:
9041 
9042 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9043 @*/
9044 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9045 {
9046   PetscErrorCode ierr;
9047 
9048   PetscFunctionBegin;
9049   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9050   if (S) PetscValidPointer(S,2);
9051   if (status) PetscValidPointer(status,3);
9052   if (S) {
9053     PetscErrorCode (*f)(Mat,Mat*);
9054 
9055     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9056     if (f) {
9057       ierr = (*f)(F,S);CHKERRQ(ierr);
9058     } else {
9059       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9060     }
9061   }
9062   if (status) *status = F->schur_status;
9063   PetscFunctionReturn(0);
9064 }
9065 
9066 /*@
9067   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9068 
9069    Logically Collective on Mat
9070 
9071    Input Parameters:
9072 +  F - the factored matrix obtained by calling MatGetFactor()
9073 .  *S - location where to return the Schur complement, can be NULL
9074 -  status - the status of the Schur complement matrix, can be NULL
9075 
9076    Notes:
9077    You must call MatFactorSetSchurIS() before calling this routine.
9078 
9079    Schur complement mode is currently implemented for sequential matrices.
9080    The routine returns a the Schur Complement stored within the data strutures of the solver.
9081    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9082    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9083 
9084    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9085 
9086    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9087 
9088    Level: advanced
9089 
9090    References:
9091 
9092 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9093 @*/
9094 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9095 {
9096   PetscFunctionBegin;
9097   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9098   if (S) PetscValidPointer(S,2);
9099   if (status) PetscValidPointer(status,3);
9100   if (S) *S = F->schur;
9101   if (status) *status = F->schur_status;
9102   PetscFunctionReturn(0);
9103 }
9104 
9105 /*@
9106   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9107 
9108    Logically Collective on Mat
9109 
9110    Input Parameters:
9111 +  F - the factored matrix obtained by calling MatGetFactor()
9112 .  *S - location where the Schur complement is stored
9113 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9114 
9115    Notes:
9116 
9117    Level: advanced
9118 
9119    References:
9120 
9121 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9122 @*/
9123 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9124 {
9125   PetscErrorCode ierr;
9126 
9127   PetscFunctionBegin;
9128   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9129   if (S) {
9130     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9131     *S = NULL;
9132   }
9133   F->schur_status = status;
9134   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9135   PetscFunctionReturn(0);
9136 }
9137 
9138 /*@
9139   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9140 
9141    Logically Collective on Mat
9142 
9143    Input Parameters:
9144 +  F - the factored matrix obtained by calling MatGetFactor()
9145 .  rhs - location where the right hand side of the Schur complement system is stored
9146 -  sol - location where the solution of the Schur complement system has to be returned
9147 
9148    Notes:
9149    The sizes of the vectors should match the size of the Schur complement
9150 
9151    Must be called after MatFactorSetSchurIS()
9152 
9153    Level: advanced
9154 
9155    References:
9156 
9157 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9158 @*/
9159 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9160 {
9161   PetscErrorCode ierr;
9162 
9163   PetscFunctionBegin;
9164   PetscValidType(F,1);
9165   PetscValidType(rhs,2);
9166   PetscValidType(sol,3);
9167   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9168   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9169   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9170   PetscCheckSameComm(F,1,rhs,2);
9171   PetscCheckSameComm(F,1,sol,3);
9172   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9173   switch (F->schur_status) {
9174   case MAT_FACTOR_SCHUR_FACTORED:
9175     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9176     break;
9177   case MAT_FACTOR_SCHUR_INVERTED:
9178     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9179     break;
9180   default:
9181     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9182     break;
9183   }
9184   PetscFunctionReturn(0);
9185 }
9186 
9187 /*@
9188   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9189 
9190    Logically Collective on Mat
9191 
9192    Input Parameters:
9193 +  F - the factored matrix obtained by calling MatGetFactor()
9194 .  rhs - location where the right hand side of the Schur complement system is stored
9195 -  sol - location where the solution of the Schur complement system has to be returned
9196 
9197    Notes:
9198    The sizes of the vectors should match the size of the Schur complement
9199 
9200    Must be called after MatFactorSetSchurIS()
9201 
9202    Level: advanced
9203 
9204    References:
9205 
9206 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9207 @*/
9208 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9209 {
9210   PetscErrorCode ierr;
9211 
9212   PetscFunctionBegin;
9213   PetscValidType(F,1);
9214   PetscValidType(rhs,2);
9215   PetscValidType(sol,3);
9216   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9217   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9218   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9219   PetscCheckSameComm(F,1,rhs,2);
9220   PetscCheckSameComm(F,1,sol,3);
9221   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9222   switch (F->schur_status) {
9223   case MAT_FACTOR_SCHUR_FACTORED:
9224     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9225     break;
9226   case MAT_FACTOR_SCHUR_INVERTED:
9227     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9228     break;
9229   default:
9230     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9231     break;
9232   }
9233   PetscFunctionReturn(0);
9234 }
9235 
9236 /*@
9237   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9238 
9239    Logically Collective on Mat
9240 
9241    Input Parameters:
9242 +  F - the factored matrix obtained by calling MatGetFactor()
9243 
9244    Notes:
9245     Must be called after MatFactorSetSchurIS().
9246 
9247    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9248 
9249    Level: advanced
9250 
9251    References:
9252 
9253 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9254 @*/
9255 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9256 {
9257   PetscErrorCode ierr;
9258 
9259   PetscFunctionBegin;
9260   PetscValidType(F,1);
9261   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9262   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9263   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9264   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9265   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9266   PetscFunctionReturn(0);
9267 }
9268 
9269 /*@
9270   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9271 
9272    Logically Collective on Mat
9273 
9274    Input Parameters:
9275 +  F - the factored matrix obtained by calling MatGetFactor()
9276 
9277    Notes:
9278     Must be called after MatFactorSetSchurIS().
9279 
9280    Level: advanced
9281 
9282    References:
9283 
9284 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9285 @*/
9286 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9287 {
9288   PetscErrorCode ierr;
9289 
9290   PetscFunctionBegin;
9291   PetscValidType(F,1);
9292   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9293   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9294   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9295   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9296   PetscFunctionReturn(0);
9297 }
9298 
9299 /*@
9300    MatPtAP - Creates the matrix product C = P^T * A * P
9301 
9302    Neighbor-wise Collective on Mat
9303 
9304    Input Parameters:
9305 +  A - the matrix
9306 .  P - the projection matrix
9307 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9308 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9309           if the result is a dense matrix this is irrelevent
9310 
9311    Output Parameters:
9312 .  C - the product matrix
9313 
9314    Notes:
9315    C will be created and must be destroyed by the user with MatDestroy().
9316 
9317    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9318    which inherit from AIJ.
9319 
9320    Level: intermediate
9321 
9322 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9323 @*/
9324 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9325 {
9326   PetscErrorCode ierr;
9327   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9328   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9329   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9330   PetscBool      sametype;
9331 
9332   PetscFunctionBegin;
9333   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9334   PetscValidType(A,1);
9335   MatCheckPreallocated(A,1);
9336   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9337   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9338   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9339   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9340   PetscValidType(P,2);
9341   MatCheckPreallocated(P,2);
9342   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9343   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9344 
9345   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);
9346   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);
9347   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9348   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9349 
9350   if (scall == MAT_REUSE_MATRIX) {
9351     PetscValidPointer(*C,5);
9352     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9353 
9354     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9355     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9356     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9357     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9358     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9359     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9360     PetscFunctionReturn(0);
9361   }
9362 
9363   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9364   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9365 
9366   fA = A->ops->ptap;
9367   fP = P->ops->ptap;
9368   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9369   if (fP == fA && sametype) {
9370     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9371     ptap = fA;
9372   } else {
9373     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9374     char ptapname[256];
9375     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9376     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9377     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9378     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9379     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9380     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9381     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);
9382   }
9383 
9384   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9385   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9386   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9387   if (A->symmetric_set && A->symmetric) {
9388     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9389   }
9390   PetscFunctionReturn(0);
9391 }
9392 
9393 /*@
9394    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9395 
9396    Neighbor-wise Collective on Mat
9397 
9398    Input Parameters:
9399 +  A - the matrix
9400 -  P - the projection matrix
9401 
9402    Output Parameters:
9403 .  C - the product matrix
9404 
9405    Notes:
9406    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9407    the user using MatDeatroy().
9408 
9409    This routine is currently only implemented for pairs of AIJ matrices and classes
9410    which inherit from AIJ.  C will be of type MATAIJ.
9411 
9412    Level: intermediate
9413 
9414 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9415 @*/
9416 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9417 {
9418   PetscErrorCode ierr;
9419 
9420   PetscFunctionBegin;
9421   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9422   PetscValidType(A,1);
9423   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9424   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9425   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9426   PetscValidType(P,2);
9427   MatCheckPreallocated(P,2);
9428   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9429   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9430   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9431   PetscValidType(C,3);
9432   MatCheckPreallocated(C,3);
9433   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9434   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);
9435   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);
9436   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);
9437   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);
9438   MatCheckPreallocated(A,1);
9439 
9440   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9441   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9442   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9443   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9444   PetscFunctionReturn(0);
9445 }
9446 
9447 /*@
9448    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9449 
9450    Neighbor-wise Collective on Mat
9451 
9452    Input Parameters:
9453 +  A - the matrix
9454 -  P - the projection matrix
9455 
9456    Output Parameters:
9457 .  C - the (i,j) structure of the product matrix
9458 
9459    Notes:
9460    C will be created and must be destroyed by the user with MatDestroy().
9461 
9462    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9463    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9464    this (i,j) structure by calling MatPtAPNumeric().
9465 
9466    Level: intermediate
9467 
9468 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9469 @*/
9470 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9471 {
9472   PetscErrorCode ierr;
9473 
9474   PetscFunctionBegin;
9475   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9476   PetscValidType(A,1);
9477   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9478   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9479   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9480   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9481   PetscValidType(P,2);
9482   MatCheckPreallocated(P,2);
9483   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9484   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9485   PetscValidPointer(C,3);
9486 
9487   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);
9488   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);
9489   MatCheckPreallocated(A,1);
9490 
9491   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9492   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9493   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9494   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9495 
9496   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9497   PetscFunctionReturn(0);
9498 }
9499 
9500 /*@
9501    MatRARt - Creates the matrix product C = R * A * R^T
9502 
9503    Neighbor-wise Collective on Mat
9504 
9505    Input Parameters:
9506 +  A - the matrix
9507 .  R - the projection matrix
9508 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9509 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9510           if the result is a dense matrix this is irrelevent
9511 
9512    Output Parameters:
9513 .  C - the product matrix
9514 
9515    Notes:
9516    C will be created and must be destroyed by the user with MatDestroy().
9517 
9518    This routine is currently only implemented for pairs of AIJ matrices and classes
9519    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9520    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9521    We recommend using MatPtAP().
9522 
9523    Level: intermediate
9524 
9525 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9526 @*/
9527 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9528 {
9529   PetscErrorCode ierr;
9530 
9531   PetscFunctionBegin;
9532   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9533   PetscValidType(A,1);
9534   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9535   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9536   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9537   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9538   PetscValidType(R,2);
9539   MatCheckPreallocated(R,2);
9540   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9541   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9542   PetscValidPointer(C,3);
9543   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);
9544 
9545   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9546   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9547   MatCheckPreallocated(A,1);
9548 
9549   if (!A->ops->rart) {
9550     Mat Rt;
9551     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9552     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9553     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9554     PetscFunctionReturn(0);
9555   }
9556   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9557   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9558   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9559   PetscFunctionReturn(0);
9560 }
9561 
9562 /*@
9563    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9564 
9565    Neighbor-wise Collective on Mat
9566 
9567    Input Parameters:
9568 +  A - the matrix
9569 -  R - the projection matrix
9570 
9571    Output Parameters:
9572 .  C - the product matrix
9573 
9574    Notes:
9575    C must have been created by calling MatRARtSymbolic and must be destroyed by
9576    the user using MatDestroy().
9577 
9578    This routine is currently only implemented for pairs of AIJ matrices and classes
9579    which inherit from AIJ.  C will be of type MATAIJ.
9580 
9581    Level: intermediate
9582 
9583 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9584 @*/
9585 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9586 {
9587   PetscErrorCode ierr;
9588 
9589   PetscFunctionBegin;
9590   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9591   PetscValidType(A,1);
9592   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9593   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9594   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9595   PetscValidType(R,2);
9596   MatCheckPreallocated(R,2);
9597   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9598   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9599   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9600   PetscValidType(C,3);
9601   MatCheckPreallocated(C,3);
9602   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9603   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);
9604   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);
9605   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);
9606   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);
9607   MatCheckPreallocated(A,1);
9608 
9609   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9610   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9611   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9612   PetscFunctionReturn(0);
9613 }
9614 
9615 /*@
9616    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9617 
9618    Neighbor-wise Collective on Mat
9619 
9620    Input Parameters:
9621 +  A - the matrix
9622 -  R - the projection matrix
9623 
9624    Output Parameters:
9625 .  C - the (i,j) structure of the product matrix
9626 
9627    Notes:
9628    C will be created and must be destroyed by the user with MatDestroy().
9629 
9630    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9631    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9632    this (i,j) structure by calling MatRARtNumeric().
9633 
9634    Level: intermediate
9635 
9636 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9637 @*/
9638 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9639 {
9640   PetscErrorCode ierr;
9641 
9642   PetscFunctionBegin;
9643   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9644   PetscValidType(A,1);
9645   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9646   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9647   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9648   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9649   PetscValidType(R,2);
9650   MatCheckPreallocated(R,2);
9651   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9652   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9653   PetscValidPointer(C,3);
9654 
9655   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);
9656   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);
9657   MatCheckPreallocated(A,1);
9658   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9659   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9660   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9661 
9662   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9663   PetscFunctionReturn(0);
9664 }
9665 
9666 /*@
9667    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9668 
9669    Neighbor-wise Collective on Mat
9670 
9671    Input Parameters:
9672 +  A - the left matrix
9673 .  B - the right matrix
9674 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9675 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9676           if the result is a dense matrix this is irrelevent
9677 
9678    Output Parameters:
9679 .  C - the product matrix
9680 
9681    Notes:
9682    Unless scall is MAT_REUSE_MATRIX C will be created.
9683 
9684    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
9685    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9686 
9687    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9688    actually needed.
9689 
9690    If you have many matrices with the same non-zero structure to multiply, you
9691    should either
9692 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9693 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9694    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
9695    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9696 
9697    Level: intermediate
9698 
9699 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9700 @*/
9701 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9702 {
9703   PetscErrorCode ierr;
9704   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9705   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9706   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9707 
9708   PetscFunctionBegin;
9709   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9710   PetscValidType(A,1);
9711   MatCheckPreallocated(A,1);
9712   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9713   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9714   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9715   PetscValidType(B,2);
9716   MatCheckPreallocated(B,2);
9717   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9718   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9719   PetscValidPointer(C,3);
9720   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9721   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);
9722   if (scall == MAT_REUSE_MATRIX) {
9723     PetscValidPointer(*C,5);
9724     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9725     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9726     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9727     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9728     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9729     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9730     PetscFunctionReturn(0);
9731   }
9732   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9733   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9734 
9735   fA = A->ops->matmult;
9736   fB = B->ops->matmult;
9737   if (fB == fA) {
9738     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9739     mult = fB;
9740   } else {
9741     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9742     char multname[256];
9743     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9744     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9745     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9746     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9747     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9748     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9749     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);
9750   }
9751   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9752   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9753   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9754   PetscFunctionReturn(0);
9755 }
9756 
9757 /*@
9758    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9759    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9760 
9761    Neighbor-wise Collective on Mat
9762 
9763    Input Parameters:
9764 +  A - the left matrix
9765 .  B - the right matrix
9766 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9767       if C is a dense matrix this is irrelevent
9768 
9769    Output Parameters:
9770 .  C - the product matrix
9771 
9772    Notes:
9773    Unless scall is MAT_REUSE_MATRIX C will be created.
9774 
9775    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9776    actually needed.
9777 
9778    This routine is currently implemented for
9779     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9780     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9781     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9782 
9783    Level: intermediate
9784 
9785    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9786      We should incorporate them into PETSc.
9787 
9788 .seealso: MatMatMult(), MatMatMultNumeric()
9789 @*/
9790 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9791 {
9792   PetscErrorCode ierr;
9793   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9794   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9795   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9796 
9797   PetscFunctionBegin;
9798   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9799   PetscValidType(A,1);
9800   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9801   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9802 
9803   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9804   PetscValidType(B,2);
9805   MatCheckPreallocated(B,2);
9806   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9807   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9808   PetscValidPointer(C,3);
9809 
9810   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);
9811   if (fill == PETSC_DEFAULT) fill = 2.0;
9812   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9813   MatCheckPreallocated(A,1);
9814 
9815   Asymbolic = A->ops->matmultsymbolic;
9816   Bsymbolic = B->ops->matmultsymbolic;
9817   if (Asymbolic == Bsymbolic) {
9818     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9819     symbolic = Bsymbolic;
9820   } else { /* dispatch based on the type of A and B */
9821     char symbolicname[256];
9822     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9823     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9824     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9825     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9826     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9827     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9828     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);
9829   }
9830   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9831   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9832   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9833   PetscFunctionReturn(0);
9834 }
9835 
9836 /*@
9837    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9838    Call this routine after first calling MatMatMultSymbolic().
9839 
9840    Neighbor-wise Collective on Mat
9841 
9842    Input Parameters:
9843 +  A - the left matrix
9844 -  B - the right matrix
9845 
9846    Output Parameters:
9847 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9848 
9849    Notes:
9850    C must have been created with MatMatMultSymbolic().
9851 
9852    This routine is currently implemented for
9853     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9854     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9855     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9856 
9857    Level: intermediate
9858 
9859 .seealso: MatMatMult(), MatMatMultSymbolic()
9860 @*/
9861 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9862 {
9863   PetscErrorCode ierr;
9864 
9865   PetscFunctionBegin;
9866   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9867   PetscFunctionReturn(0);
9868 }
9869 
9870 /*@
9871    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9872 
9873    Neighbor-wise Collective on Mat
9874 
9875    Input Parameters:
9876 +  A - the left matrix
9877 .  B - the right matrix
9878 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9879 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9880 
9881    Output Parameters:
9882 .  C - the product matrix
9883 
9884    Notes:
9885    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9886 
9887    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9888 
9889   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9890    actually needed.
9891 
9892    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9893 
9894    Level: intermediate
9895 
9896 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9897 @*/
9898 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9899 {
9900   PetscErrorCode ierr;
9901   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9902   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9903 
9904   PetscFunctionBegin;
9905   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9906   PetscValidType(A,1);
9907   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9908   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9909   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9910   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9911   PetscValidType(B,2);
9912   MatCheckPreallocated(B,2);
9913   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9914   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9915   PetscValidPointer(C,3);
9916   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);
9917   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9918   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9919   MatCheckPreallocated(A,1);
9920 
9921   fA = A->ops->mattransposemult;
9922   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9923   fB = B->ops->mattransposemult;
9924   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9925   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);
9926 
9927   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9928   if (scall == MAT_INITIAL_MATRIX) {
9929     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9930     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9931     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9932   }
9933   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9934   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9935   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9936   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9937   PetscFunctionReturn(0);
9938 }
9939 
9940 /*@
9941    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9942 
9943    Neighbor-wise Collective on Mat
9944 
9945    Input Parameters:
9946 +  A - the left matrix
9947 .  B - the right matrix
9948 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9949 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9950 
9951    Output Parameters:
9952 .  C - the product matrix
9953 
9954    Notes:
9955    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9956 
9957    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9958 
9959   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9960    actually needed.
9961 
9962    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9963    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9964 
9965    Level: intermediate
9966 
9967 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9968 @*/
9969 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9970 {
9971   PetscErrorCode ierr;
9972   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9973   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9974   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9975 
9976   PetscFunctionBegin;
9977   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9978   PetscValidType(A,1);
9979   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9980   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9981   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9982   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9983   PetscValidType(B,2);
9984   MatCheckPreallocated(B,2);
9985   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9986   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9987   PetscValidPointer(C,3);
9988   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);
9989   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9990   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9991   MatCheckPreallocated(A,1);
9992 
9993   fA = A->ops->transposematmult;
9994   fB = B->ops->transposematmult;
9995   if (fB==fA) {
9996     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9997     transposematmult = fA;
9998   } else {
9999     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10000     char multname[256];
10001     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10002     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10003     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10004     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10005     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10006     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10007     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);
10008   }
10009   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10010   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10011   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10012   PetscFunctionReturn(0);
10013 }
10014 
10015 /*@
10016    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10017 
10018    Neighbor-wise Collective on Mat
10019 
10020    Input Parameters:
10021 +  A - the left matrix
10022 .  B - the middle matrix
10023 .  C - the right matrix
10024 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10025 -  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
10026           if the result is a dense matrix this is irrelevent
10027 
10028    Output Parameters:
10029 .  D - the product matrix
10030 
10031    Notes:
10032    Unless scall is MAT_REUSE_MATRIX D will be created.
10033 
10034    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10035 
10036    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10037    actually needed.
10038 
10039    If you have many matrices with the same non-zero structure to multiply, you
10040    should use MAT_REUSE_MATRIX in all calls but the first or
10041 
10042    Level: intermediate
10043 
10044 .seealso: MatMatMult, MatPtAP()
10045 @*/
10046 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10047 {
10048   PetscErrorCode ierr;
10049   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10050   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10051   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10052   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10053 
10054   PetscFunctionBegin;
10055   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10056   PetscValidType(A,1);
10057   MatCheckPreallocated(A,1);
10058   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10059   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10060   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10061   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10062   PetscValidType(B,2);
10063   MatCheckPreallocated(B,2);
10064   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10065   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10066   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10067   PetscValidPointer(C,3);
10068   MatCheckPreallocated(C,3);
10069   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10070   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10071   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);
10072   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);
10073   if (scall == MAT_REUSE_MATRIX) {
10074     PetscValidPointer(*D,6);
10075     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10076     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10077     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10078     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10079     PetscFunctionReturn(0);
10080   }
10081   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10082   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10083 
10084   fA = A->ops->matmatmult;
10085   fB = B->ops->matmatmult;
10086   fC = C->ops->matmatmult;
10087   if (fA == fB && fA == fC) {
10088     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10089     mult = fA;
10090   } else {
10091     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10092     char multname[256];
10093     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10094     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10095     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10096     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10097     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10098     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10099     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10100     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10101     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);
10102   }
10103   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10104   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10105   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10106   PetscFunctionReturn(0);
10107 }
10108 
10109 /*@
10110    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10111 
10112    Collective on Mat
10113 
10114    Input Parameters:
10115 +  mat - the matrix
10116 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10117 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10118 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10119 
10120    Output Parameter:
10121 .  matredundant - redundant matrix
10122 
10123    Notes:
10124    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10125    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10126 
10127    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10128    calling it.
10129 
10130    Level: advanced
10131 
10132    Concepts: subcommunicator
10133    Concepts: duplicate matrix
10134 
10135 .seealso: MatDestroy()
10136 @*/
10137 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10138 {
10139   PetscErrorCode ierr;
10140   MPI_Comm       comm;
10141   PetscMPIInt    size;
10142   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10143   Mat_Redundant  *redund=NULL;
10144   PetscSubcomm   psubcomm=NULL;
10145   MPI_Comm       subcomm_in=subcomm;
10146   Mat            *matseq;
10147   IS             isrow,iscol;
10148   PetscBool      newsubcomm=PETSC_FALSE;
10149 
10150   PetscFunctionBegin;
10151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10152   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10153     PetscValidPointer(*matredundant,5);
10154     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10155   }
10156 
10157   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10158   if (size == 1 || nsubcomm == 1) {
10159     if (reuse == MAT_INITIAL_MATRIX) {
10160       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10161     } else {
10162       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");
10163       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10164     }
10165     PetscFunctionReturn(0);
10166   }
10167 
10168   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10169   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10170   MatCheckPreallocated(mat,1);
10171 
10172   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10173   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10174     /* create psubcomm, then get subcomm */
10175     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10176     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10177     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10178 
10179     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10180     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10181     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10182     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10183     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10184     newsubcomm = PETSC_TRUE;
10185     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10186   }
10187 
10188   /* get isrow, iscol and a local sequential matrix matseq[0] */
10189   if (reuse == MAT_INITIAL_MATRIX) {
10190     mloc_sub = PETSC_DECIDE;
10191     nloc_sub = PETSC_DECIDE;
10192     if (bs < 1) {
10193       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10194       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10195     } else {
10196       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10197       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10198     }
10199     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10200     rstart = rend - mloc_sub;
10201     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10202     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10203   } else { /* reuse == MAT_REUSE_MATRIX */
10204     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");
10205     /* retrieve subcomm */
10206     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10207     redund = (*matredundant)->redundant;
10208     isrow  = redund->isrow;
10209     iscol  = redund->iscol;
10210     matseq = redund->matseq;
10211   }
10212   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10213 
10214   /* get matredundant over subcomm */
10215   if (reuse == MAT_INITIAL_MATRIX) {
10216     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10217 
10218     /* create a supporting struct and attach it to C for reuse */
10219     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10220     (*matredundant)->redundant = redund;
10221     redund->isrow              = isrow;
10222     redund->iscol              = iscol;
10223     redund->matseq             = matseq;
10224     if (newsubcomm) {
10225       redund->subcomm          = subcomm;
10226     } else {
10227       redund->subcomm          = MPI_COMM_NULL;
10228     }
10229   } else {
10230     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10231   }
10232   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10233   PetscFunctionReturn(0);
10234 }
10235 
10236 /*@C
10237    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10238    a given 'mat' object. Each submatrix can span multiple procs.
10239 
10240    Collective on Mat
10241 
10242    Input Parameters:
10243 +  mat - the matrix
10244 .  subcomm - the subcommunicator obtained by com_split(comm)
10245 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10246 
10247    Output Parameter:
10248 .  subMat - 'parallel submatrices each spans a given subcomm
10249 
10250   Notes:
10251   The submatrix partition across processors is dictated by 'subComm' a
10252   communicator obtained by com_split(comm). The comm_split
10253   is not restriced to be grouped with consecutive original ranks.
10254 
10255   Due the comm_split() usage, the parallel layout of the submatrices
10256   map directly to the layout of the original matrix [wrt the local
10257   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10258   into the 'DiagonalMat' of the subMat, hence it is used directly from
10259   the subMat. However the offDiagMat looses some columns - and this is
10260   reconstructed with MatSetValues()
10261 
10262   Level: advanced
10263 
10264   Concepts: subcommunicator
10265   Concepts: submatrices
10266 
10267 .seealso: MatCreateSubMatrices()
10268 @*/
10269 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10270 {
10271   PetscErrorCode ierr;
10272   PetscMPIInt    commsize,subCommSize;
10273 
10274   PetscFunctionBegin;
10275   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10276   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10277   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10278 
10279   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");
10280   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10281   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10282   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10283   PetscFunctionReturn(0);
10284 }
10285 
10286 /*@
10287    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10288 
10289    Not Collective
10290 
10291    Input Arguments:
10292    mat - matrix to extract local submatrix from
10293    isrow - local row indices for submatrix
10294    iscol - local column indices for submatrix
10295 
10296    Output Arguments:
10297    submat - the submatrix
10298 
10299    Level: intermediate
10300 
10301    Notes:
10302    The submat should be returned with MatRestoreLocalSubMatrix().
10303 
10304    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10305    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10306 
10307    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10308    MatSetValuesBlockedLocal() will also be implemented.
10309 
10310    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10311    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10312 
10313 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10314 @*/
10315 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10316 {
10317   PetscErrorCode ierr;
10318 
10319   PetscFunctionBegin;
10320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10321   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10322   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10323   PetscCheckSameComm(isrow,2,iscol,3);
10324   PetscValidPointer(submat,4);
10325   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10326 
10327   if (mat->ops->getlocalsubmatrix) {
10328     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10329   } else {
10330     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10331   }
10332   PetscFunctionReturn(0);
10333 }
10334 
10335 /*@
10336    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10337 
10338    Not Collective
10339 
10340    Input Arguments:
10341    mat - matrix to extract local submatrix from
10342    isrow - local row indices for submatrix
10343    iscol - local column indices for submatrix
10344    submat - the submatrix
10345 
10346    Level: intermediate
10347 
10348 .seealso: MatGetLocalSubMatrix()
10349 @*/
10350 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10351 {
10352   PetscErrorCode ierr;
10353 
10354   PetscFunctionBegin;
10355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10356   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10357   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10358   PetscCheckSameComm(isrow,2,iscol,3);
10359   PetscValidPointer(submat,4);
10360   if (*submat) {
10361     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10362   }
10363 
10364   if (mat->ops->restorelocalsubmatrix) {
10365     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10366   } else {
10367     ierr = MatDestroy(submat);CHKERRQ(ierr);
10368   }
10369   *submat = NULL;
10370   PetscFunctionReturn(0);
10371 }
10372 
10373 /* --------------------------------------------------------*/
10374 /*@
10375    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10376 
10377    Collective on Mat
10378 
10379    Input Parameter:
10380 .  mat - the matrix
10381 
10382    Output Parameter:
10383 .  is - if any rows have zero diagonals this contains the list of them
10384 
10385    Level: developer
10386 
10387    Concepts: matrix-vector product
10388 
10389 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10390 @*/
10391 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10392 {
10393   PetscErrorCode ierr;
10394 
10395   PetscFunctionBegin;
10396   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10397   PetscValidType(mat,1);
10398   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10399   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10400 
10401   if (!mat->ops->findzerodiagonals) {
10402     Vec                diag;
10403     const PetscScalar *a;
10404     PetscInt          *rows;
10405     PetscInt           rStart, rEnd, r, nrow = 0;
10406 
10407     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10408     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10409     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10410     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10411     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10412     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10413     nrow = 0;
10414     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10415     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10416     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10417     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10418   } else {
10419     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10420   }
10421   PetscFunctionReturn(0);
10422 }
10423 
10424 /*@
10425    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10426 
10427    Collective on Mat
10428 
10429    Input Parameter:
10430 .  mat - the matrix
10431 
10432    Output Parameter:
10433 .  is - contains the list of rows with off block diagonal entries
10434 
10435    Level: developer
10436 
10437    Concepts: matrix-vector product
10438 
10439 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10440 @*/
10441 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10442 {
10443   PetscErrorCode ierr;
10444 
10445   PetscFunctionBegin;
10446   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10447   PetscValidType(mat,1);
10448   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10449   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10450 
10451   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10452   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10453   PetscFunctionReturn(0);
10454 }
10455 
10456 /*@C
10457   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10458 
10459   Collective on Mat
10460 
10461   Input Parameters:
10462 . mat - the matrix
10463 
10464   Output Parameters:
10465 . values - the block inverses in column major order (FORTRAN-like)
10466 
10467    Note:
10468    This routine is not available from Fortran.
10469 
10470   Level: advanced
10471 
10472 .seealso: MatInvertBockDiagonalMat
10473 @*/
10474 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10475 {
10476   PetscErrorCode ierr;
10477 
10478   PetscFunctionBegin;
10479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10480   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10481   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10482   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10483   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10484   PetscFunctionReturn(0);
10485 }
10486 
10487 /*@C
10488   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10489 
10490   Collective on Mat
10491 
10492   Input Parameters:
10493 + mat - the matrix
10494 . nblocks - the number of blocks
10495 - bsizes - the size of each block
10496 
10497   Output Parameters:
10498 . values - the block inverses in column major order (FORTRAN-like)
10499 
10500    Note:
10501    This routine is not available from Fortran.
10502 
10503   Level: advanced
10504 
10505 .seealso: MatInvertBockDiagonal()
10506 @*/
10507 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10508 {
10509   PetscErrorCode ierr;
10510 
10511   PetscFunctionBegin;
10512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10513   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10514   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10515   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10516   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10517   PetscFunctionReturn(0);
10518 }
10519 
10520 /*@
10521   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10522 
10523   Collective on Mat
10524 
10525   Input Parameters:
10526 . A - the matrix
10527 
10528   Output Parameters:
10529 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10530 
10531   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10532 
10533   Level: advanced
10534 
10535 .seealso: MatInvertBockDiagonal()
10536 @*/
10537 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10538 {
10539   PetscErrorCode     ierr;
10540   const PetscScalar *vals;
10541   PetscInt          *dnnz;
10542   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10543 
10544   PetscFunctionBegin;
10545   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10546   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10547   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10548   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10549   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10550   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10551   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10552   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10553   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10554   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10555   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10556   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10557   for (i = rstart/bs; i < rend/bs; i++) {
10558     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10559   }
10560   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10561   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10562   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10563   PetscFunctionReturn(0);
10564 }
10565 
10566 /*@C
10567     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10568     via MatTransposeColoringCreate().
10569 
10570     Collective on MatTransposeColoring
10571 
10572     Input Parameter:
10573 .   c - coloring context
10574 
10575     Level: intermediate
10576 
10577 .seealso: MatTransposeColoringCreate()
10578 @*/
10579 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10580 {
10581   PetscErrorCode       ierr;
10582   MatTransposeColoring matcolor=*c;
10583 
10584   PetscFunctionBegin;
10585   if (!matcolor) PetscFunctionReturn(0);
10586   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10587 
10588   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10589   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10590   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10591   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10592   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10593   if (matcolor->brows>0) {
10594     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10595   }
10596   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10597   PetscFunctionReturn(0);
10598 }
10599 
10600 /*@C
10601     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10602     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10603     MatTransposeColoring to sparse B.
10604 
10605     Collective on MatTransposeColoring
10606 
10607     Input Parameters:
10608 +   B - sparse matrix B
10609 .   Btdense - symbolic dense matrix B^T
10610 -   coloring - coloring context created with MatTransposeColoringCreate()
10611 
10612     Output Parameter:
10613 .   Btdense - dense matrix B^T
10614 
10615     Level: advanced
10616 
10617      Notes:
10618     These are used internally for some implementations of MatRARt()
10619 
10620 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10621 
10622 .keywords: coloring
10623 @*/
10624 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10625 {
10626   PetscErrorCode ierr;
10627 
10628   PetscFunctionBegin;
10629   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10630   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10631   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10632 
10633   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10634   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10635   PetscFunctionReturn(0);
10636 }
10637 
10638 /*@C
10639     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10640     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10641     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10642     Csp from Cden.
10643 
10644     Collective on MatTransposeColoring
10645 
10646     Input Parameters:
10647 +   coloring - coloring context created with MatTransposeColoringCreate()
10648 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10649 
10650     Output Parameter:
10651 .   Csp - sparse matrix
10652 
10653     Level: advanced
10654 
10655      Notes:
10656     These are used internally for some implementations of MatRARt()
10657 
10658 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10659 
10660 .keywords: coloring
10661 @*/
10662 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10663 {
10664   PetscErrorCode ierr;
10665 
10666   PetscFunctionBegin;
10667   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10668   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10669   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10670 
10671   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10672   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10673   PetscFunctionReturn(0);
10674 }
10675 
10676 /*@C
10677    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10678 
10679    Collective on Mat
10680 
10681    Input Parameters:
10682 +  mat - the matrix product C
10683 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10684 
10685     Output Parameter:
10686 .   color - the new coloring context
10687 
10688     Level: intermediate
10689 
10690 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10691            MatTransColoringApplyDenToSp()
10692 @*/
10693 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10694 {
10695   MatTransposeColoring c;
10696   MPI_Comm             comm;
10697   PetscErrorCode       ierr;
10698 
10699   PetscFunctionBegin;
10700   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10701   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10702   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10703 
10704   c->ctype = iscoloring->ctype;
10705   if (mat->ops->transposecoloringcreate) {
10706     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10707   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10708 
10709   *color = c;
10710   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10711   PetscFunctionReturn(0);
10712 }
10713 
10714 /*@
10715       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10716         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10717         same, otherwise it will be larger
10718 
10719      Not Collective
10720 
10721   Input Parameter:
10722 .    A  - the matrix
10723 
10724   Output Parameter:
10725 .    state - the current state
10726 
10727   Notes:
10728     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10729          different matrices
10730 
10731   Level: intermediate
10732 
10733 @*/
10734 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10735 {
10736   PetscFunctionBegin;
10737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10738   *state = mat->nonzerostate;
10739   PetscFunctionReturn(0);
10740 }
10741 
10742 /*@
10743       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10744                  matrices from each processor
10745 
10746     Collective on MPI_Comm
10747 
10748    Input Parameters:
10749 +    comm - the communicators the parallel matrix will live on
10750 .    seqmat - the input sequential matrices
10751 .    n - number of local columns (or PETSC_DECIDE)
10752 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10753 
10754    Output Parameter:
10755 .    mpimat - the parallel matrix generated
10756 
10757     Level: advanced
10758 
10759    Notes:
10760     The number of columns of the matrix in EACH processor MUST be the same.
10761 
10762 @*/
10763 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10764 {
10765   PetscErrorCode ierr;
10766 
10767   PetscFunctionBegin;
10768   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10769   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");
10770 
10771   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10772   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10773   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10774   PetscFunctionReturn(0);
10775 }
10776 
10777 /*@
10778      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10779                  ranks' ownership ranges.
10780 
10781     Collective on A
10782 
10783    Input Parameters:
10784 +    A   - the matrix to create subdomains from
10785 -    N   - requested number of subdomains
10786 
10787 
10788    Output Parameters:
10789 +    n   - number of subdomains resulting on this rank
10790 -    iss - IS list with indices of subdomains on this rank
10791 
10792     Level: advanced
10793 
10794     Notes:
10795     number of subdomains must be smaller than the communicator size
10796 @*/
10797 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10798 {
10799   MPI_Comm        comm,subcomm;
10800   PetscMPIInt     size,rank,color;
10801   PetscInt        rstart,rend,k;
10802   PetscErrorCode  ierr;
10803 
10804   PetscFunctionBegin;
10805   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10806   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10807   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10808   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);
10809   *n = 1;
10810   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10811   color = rank/k;
10812   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10813   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10814   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10815   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10816   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10817   PetscFunctionReturn(0);
10818 }
10819 
10820 /*@
10821    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10822 
10823    If the interpolation and restriction operators are the same, uses MatPtAP.
10824    If they are not the same, use MatMatMatMult.
10825 
10826    Once the coarse grid problem is constructed, correct for interpolation operators
10827    that are not of full rank, which can legitimately happen in the case of non-nested
10828    geometric multigrid.
10829 
10830    Input Parameters:
10831 +  restrct - restriction operator
10832 .  dA - fine grid matrix
10833 .  interpolate - interpolation operator
10834 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10835 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10836 
10837    Output Parameters:
10838 .  A - the Galerkin coarse matrix
10839 
10840    Options Database Key:
10841 .  -pc_mg_galerkin <both,pmat,mat,none>
10842 
10843    Level: developer
10844 
10845 .keywords: MG, multigrid, Galerkin
10846 
10847 .seealso: MatPtAP(), MatMatMatMult()
10848 @*/
10849 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10850 {
10851   PetscErrorCode ierr;
10852   IS             zerorows;
10853   Vec            diag;
10854 
10855   PetscFunctionBegin;
10856   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10857   /* Construct the coarse grid matrix */
10858   if (interpolate == restrct) {
10859     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10860   } else {
10861     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10862   }
10863 
10864   /* If the interpolation matrix is not of full rank, A will have zero rows.
10865      This can legitimately happen in the case of non-nested geometric multigrid.
10866      In that event, we set the rows of the matrix to the rows of the identity,
10867      ignoring the equations (as the RHS will also be zero). */
10868 
10869   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10870 
10871   if (zerorows != NULL) { /* if there are any zero rows */
10872     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10873     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10874     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10875     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10876     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10877     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10878   }
10879   PetscFunctionReturn(0);
10880 }
10881 
10882 /*@C
10883     MatSetOperation - Allows user to set a matrix operation for any matrix type
10884 
10885    Logically Collective on Mat
10886 
10887     Input Parameters:
10888 +   mat - the matrix
10889 .   op - the name of the operation
10890 -   f - the function that provides the operation
10891 
10892    Level: developer
10893 
10894     Usage:
10895 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10896 $      ierr = MatCreateXXX(comm,...&A);
10897 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10898 
10899     Notes:
10900     See the file include/petscmat.h for a complete list of matrix
10901     operations, which all have the form MATOP_<OPERATION>, where
10902     <OPERATION> is the name (in all capital letters) of the
10903     user interface routine (e.g., MatMult() -> MATOP_MULT).
10904 
10905     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10906     sequence as the usual matrix interface routines, since they
10907     are intended to be accessed via the usual matrix interface
10908     routines, e.g.,
10909 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10910 
10911     In particular each function MUST return an error code of 0 on success and
10912     nonzero on failure.
10913 
10914     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10915 
10916 .keywords: matrix, set, operation
10917 
10918 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10919 @*/
10920 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10921 {
10922   PetscFunctionBegin;
10923   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10924   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10925     mat->ops->viewnative = mat->ops->view;
10926   }
10927   (((void(**)(void))mat->ops)[op]) = f;
10928   PetscFunctionReturn(0);
10929 }
10930 
10931 /*@C
10932     MatGetOperation - Gets a matrix operation for any matrix type.
10933 
10934     Not Collective
10935 
10936     Input Parameters:
10937 +   mat - the matrix
10938 -   op - the name of the operation
10939 
10940     Output Parameter:
10941 .   f - the function that provides the operation
10942 
10943     Level: developer
10944 
10945     Usage:
10946 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10947 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10948 
10949     Notes:
10950     See the file include/petscmat.h for a complete list of matrix
10951     operations, which all have the form MATOP_<OPERATION>, where
10952     <OPERATION> is the name (in all capital letters) of the
10953     user interface routine (e.g., MatMult() -> MATOP_MULT).
10954 
10955     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10956 
10957 .keywords: matrix, get, operation
10958 
10959 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10960 @*/
10961 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10962 {
10963   PetscFunctionBegin;
10964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10965   *f = (((void (**)(void))mat->ops)[op]);
10966   PetscFunctionReturn(0);
10967 }
10968 
10969 /*@
10970     MatHasOperation - Determines whether the given matrix supports the particular
10971     operation.
10972 
10973    Not Collective
10974 
10975    Input Parameters:
10976 +  mat - the matrix
10977 -  op - the operation, for example, MATOP_GET_DIAGONAL
10978 
10979    Output Parameter:
10980 .  has - either PETSC_TRUE or PETSC_FALSE
10981 
10982    Level: advanced
10983 
10984    Notes:
10985    See the file include/petscmat.h for a complete list of matrix
10986    operations, which all have the form MATOP_<OPERATION>, where
10987    <OPERATION> is the name (in all capital letters) of the
10988    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10989 
10990 .keywords: matrix, has, operation
10991 
10992 .seealso: MatCreateShell()
10993 @*/
10994 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10995 {
10996   PetscErrorCode ierr;
10997 
10998   PetscFunctionBegin;
10999   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11000   PetscValidType(mat,1);
11001   PetscValidPointer(has,3);
11002   if (mat->ops->hasoperation) {
11003     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11004   } else {
11005     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11006     else {
11007       *has = PETSC_FALSE;
11008       if (op == MATOP_CREATE_SUBMATRIX) {
11009         PetscMPIInt size;
11010 
11011         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11012         if (size == 1) {
11013           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11014         }
11015       }
11016     }
11017   }
11018   PetscFunctionReturn(0);
11019 }
11020 
11021 /*@
11022     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11023     of the matrix are congruent
11024 
11025    Collective on mat
11026 
11027    Input Parameters:
11028 .  mat - the matrix
11029 
11030    Output Parameter:
11031 .  cong - either PETSC_TRUE or PETSC_FALSE
11032 
11033    Level: beginner
11034 
11035    Notes:
11036 
11037 .keywords: matrix, has
11038 
11039 .seealso: MatCreate(), MatSetSizes()
11040 @*/
11041 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11042 {
11043   PetscErrorCode ierr;
11044 
11045   PetscFunctionBegin;
11046   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11047   PetscValidType(mat,1);
11048   PetscValidPointer(cong,2);
11049   if (!mat->rmap || !mat->cmap) {
11050     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11051     PetscFunctionReturn(0);
11052   }
11053   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11054     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11055     if (*cong) mat->congruentlayouts = 1;
11056     else       mat->congruentlayouts = 0;
11057   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11058   PetscFunctionReturn(0);
11059 }
11060