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