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