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