xref: /petsc/src/mat/interface/matrix.c (revision 6e5f5dad97d5d0d453d1db100f9dbfcf5747de2b)
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->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3237   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);
3238   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);
3239   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);
3240   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
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->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3339   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);
3340   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);
3341   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);
3342   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");
3343   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
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->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3404   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3405   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3406   if (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);
3407   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");
3408   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
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->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3472   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3473   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);
3474   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);
3475   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);
3476   MatCheckPreallocated(mat,1);
3477   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3478   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3479   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3480   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3481   PetscFunctionReturn(0);
3482 }
3483 
3484 /*@
3485    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3486                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3487 
3488    Neighbor-wise Collective on Mat and Vec
3489 
3490    Input Parameters:
3491 +  mat - the factored matrix
3492 -  b - the right-hand-side vector
3493 
3494    Output Parameter:
3495 .  x - the result vector
3496 
3497    Notes:
3498    MatSolve() should be used for most applications, as it performs
3499    a forward solve followed by a backward solve.
3500 
3501    The vectors b and x cannot be the same.  I.e., one cannot
3502    call MatBackwardSolve(A,x,x).
3503 
3504    For matrix in seqsbaij format with block size larger than 1,
3505    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3506    MatForwardSolve() solves U^T*D y = b, and
3507    MatBackwardSolve() solves U x = y.
3508    Thus they do not provide a symmetric preconditioner.
3509 
3510    Most users should employ the simplified KSP interface for linear solvers
3511    instead of working directly with matrix algebra routines such as this.
3512    See, e.g., KSPCreate().
3513 
3514    Level: developer
3515 
3516    Concepts: matrices^backward solves
3517 
3518 .seealso: MatSolve(), MatForwardSolve()
3519 @*/
3520 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3521 {
3522   PetscErrorCode ierr;
3523 
3524   PetscFunctionBegin;
3525   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3526   PetscValidType(mat,1);
3527   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3528   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3529   PetscCheckSameComm(mat,1,b,2);
3530   PetscCheckSameComm(mat,1,x,3);
3531   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3532   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
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   MatCheckPreallocated(mat,1);
3538 
3539   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3540   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3541   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3542   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3543   PetscFunctionReturn(0);
3544 }
3545 
3546 /*@
3547    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3548 
3549    Neighbor-wise Collective on Mat and Vec
3550 
3551    Input Parameters:
3552 +  mat - the factored matrix
3553 .  b - the right-hand-side vector
3554 -  y - the vector to be added to
3555 
3556    Output Parameter:
3557 .  x - the result vector
3558 
3559    Notes:
3560    The vectors b and x cannot be the same.  I.e., one cannot
3561    call MatSolveAdd(A,x,y,x).
3562 
3563    Most users should employ the simplified KSP interface for linear solvers
3564    instead of working directly with matrix algebra routines such as this.
3565    See, e.g., KSPCreate().
3566 
3567    Level: developer
3568 
3569    Concepts: matrices^triangular solves
3570 
3571 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3572 @*/
3573 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3574 {
3575   PetscScalar    one = 1.0;
3576   Vec            tmp;
3577   PetscErrorCode ierr;
3578 
3579   PetscFunctionBegin;
3580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3581   PetscValidType(mat,1);
3582   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3583   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3584   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3585   PetscCheckSameComm(mat,1,b,2);
3586   PetscCheckSameComm(mat,1,y,2);
3587   PetscCheckSameComm(mat,1,x,3);
3588   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3589   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3590   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);
3591   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);
3592   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);
3593   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);
3594   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);
3595   MatCheckPreallocated(mat,1);
3596 
3597   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3598   if (mat->ops->solveadd) {
3599     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3600   } else {
3601     /* do the solve then the add manually */
3602     if (x != y) {
3603       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3604       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3605     } else {
3606       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3607       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3608       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3609       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3610       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3611       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3612     }
3613   }
3614   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3615   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3616   PetscFunctionReturn(0);
3617 }
3618 
3619 /*@
3620    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3621 
3622    Neighbor-wise Collective on Mat and Vec
3623 
3624    Input Parameters:
3625 +  mat - the factored matrix
3626 -  b - the right-hand-side vector
3627 
3628    Output Parameter:
3629 .  x - the result vector
3630 
3631    Notes:
3632    The vectors b and x cannot be the same.  I.e., one cannot
3633    call MatSolveTranspose(A,x,x).
3634 
3635    Most users should employ the simplified KSP interface for linear solvers
3636    instead of working directly with matrix algebra routines such as this.
3637    See, e.g., KSPCreate().
3638 
3639    Level: developer
3640 
3641    Concepts: matrices^triangular solves
3642 
3643 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3644 @*/
3645 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3646 {
3647   PetscErrorCode ierr;
3648 
3649   PetscFunctionBegin;
3650   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3651   PetscValidType(mat,1);
3652   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3653   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3654   PetscCheckSameComm(mat,1,b,2);
3655   PetscCheckSameComm(mat,1,x,3);
3656   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3657   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3658   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3659   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);
3660   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);
3661   MatCheckPreallocated(mat,1);
3662   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3663   if (mat->factorerrortype) {
3664     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3665     ierr = VecSetInf(x);CHKERRQ(ierr);
3666   } else {
3667     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3668   }
3669   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3670   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3671   PetscFunctionReturn(0);
3672 }
3673 
3674 /*@
3675    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3676                       factored matrix.
3677 
3678    Neighbor-wise Collective on Mat and Vec
3679 
3680    Input Parameters:
3681 +  mat - the factored matrix
3682 .  b - the right-hand-side vector
3683 -  y - the vector to be added to
3684 
3685    Output Parameter:
3686 .  x - the result vector
3687 
3688    Notes:
3689    The vectors b and x cannot be the same.  I.e., one cannot
3690    call MatSolveTransposeAdd(A,x,y,x).
3691 
3692    Most users should employ the simplified KSP interface for linear solvers
3693    instead of working directly with matrix algebra routines such as this.
3694    See, e.g., KSPCreate().
3695 
3696    Level: developer
3697 
3698    Concepts: matrices^triangular solves
3699 
3700 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3701 @*/
3702 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3703 {
3704   PetscScalar    one = 1.0;
3705   PetscErrorCode ierr;
3706   Vec            tmp;
3707 
3708   PetscFunctionBegin;
3709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3710   PetscValidType(mat,1);
3711   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3712   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3713   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3714   PetscCheckSameComm(mat,1,b,2);
3715   PetscCheckSameComm(mat,1,y,3);
3716   PetscCheckSameComm(mat,1,x,4);
3717   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3718   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3719   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);
3720   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);
3721   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);
3722   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);
3723   MatCheckPreallocated(mat,1);
3724 
3725   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3726   if (mat->ops->solvetransposeadd) {
3727     if (mat->factorerrortype) {
3728       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3729       ierr = VecSetInf(x);CHKERRQ(ierr);
3730     } else {
3731       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3732     }
3733   } else {
3734     /* do the solve then the add manually */
3735     if (x != y) {
3736       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3737       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3738     } else {
3739       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3740       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3741       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3742       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3743       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3744       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3745     }
3746   }
3747   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3748   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3749   PetscFunctionReturn(0);
3750 }
3751 /* ----------------------------------------------------------------*/
3752 
3753 /*@
3754    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3755 
3756    Neighbor-wise Collective on Mat and Vec
3757 
3758    Input Parameters:
3759 +  mat - the matrix
3760 .  b - the right hand side
3761 .  omega - the relaxation factor
3762 .  flag - flag indicating the type of SOR (see below)
3763 .  shift -  diagonal shift
3764 .  its - the number of iterations
3765 -  lits - the number of local iterations
3766 
3767    Output Parameters:
3768 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3769 
3770    SOR Flags:
3771 .     SOR_FORWARD_SWEEP - forward SOR
3772 .     SOR_BACKWARD_SWEEP - backward SOR
3773 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3774 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3775 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3776 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3777 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3778          upper/lower triangular part of matrix to
3779          vector (with omega)
3780 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3781 
3782    Notes:
3783    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3784    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3785    on each processor.
3786 
3787    Application programmers will not generally use MatSOR() directly,
3788    but instead will employ the KSP/PC interface.
3789 
3790    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3791 
3792    Notes for Advanced Users:
3793    The flags are implemented as bitwise inclusive or operations.
3794    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3795    to specify a zero initial guess for SSOR.
3796 
3797    Most users should employ the simplified KSP interface for linear solvers
3798    instead of working directly with matrix algebra routines such as this.
3799    See, e.g., KSPCreate().
3800 
3801    Vectors x and b CANNOT be the same
3802 
3803    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3804 
3805    Level: developer
3806 
3807    Concepts: matrices^relaxation
3808    Concepts: matrices^SOR
3809    Concepts: matrices^Gauss-Seidel
3810 
3811 @*/
3812 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3813 {
3814   PetscErrorCode ierr;
3815 
3816   PetscFunctionBegin;
3817   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3818   PetscValidType(mat,1);
3819   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3820   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3821   PetscCheckSameComm(mat,1,b,2);
3822   PetscCheckSameComm(mat,1,x,8);
3823   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3824   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3825   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3826   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);
3827   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);
3828   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);
3829   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3830   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3831   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3832 
3833   MatCheckPreallocated(mat,1);
3834   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3835   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3836   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3837   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3838   PetscFunctionReturn(0);
3839 }
3840 
3841 /*
3842       Default matrix copy routine.
3843 */
3844 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3845 {
3846   PetscErrorCode    ierr;
3847   PetscInt          i,rstart = 0,rend = 0,nz;
3848   const PetscInt    *cwork;
3849   const PetscScalar *vwork;
3850 
3851   PetscFunctionBegin;
3852   if (B->assembled) {
3853     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3854   }
3855   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3856   for (i=rstart; i<rend; i++) {
3857     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3858     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3859     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3860   }
3861   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3862   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3863   PetscFunctionReturn(0);
3864 }
3865 
3866 /*@
3867    MatCopy - Copys a matrix to another matrix.
3868 
3869    Collective on Mat
3870 
3871    Input Parameters:
3872 +  A - the matrix
3873 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3874 
3875    Output Parameter:
3876 .  B - where the copy is put
3877 
3878    Notes:
3879    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3880    same nonzero pattern or the routine will crash.
3881 
3882    MatCopy() copies the matrix entries of a matrix to another existing
3883    matrix (after first zeroing the second matrix).  A related routine is
3884    MatConvert(), which first creates a new matrix and then copies the data.
3885 
3886    Level: intermediate
3887 
3888    Concepts: matrices^copying
3889 
3890 .seealso: MatConvert(), MatDuplicate()
3891 
3892 @*/
3893 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3894 {
3895   PetscErrorCode ierr;
3896   PetscInt       i;
3897 
3898   PetscFunctionBegin;
3899   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3900   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3901   PetscValidType(A,1);
3902   PetscValidType(B,2);
3903   PetscCheckSameComm(A,1,B,2);
3904   MatCheckPreallocated(B,2);
3905   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3906   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3907   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);
3908   MatCheckPreallocated(A,1);
3909   if (A == B) PetscFunctionReturn(0);
3910 
3911   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3912   if (A->ops->copy) {
3913     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3914   } else { /* generic conversion */
3915     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3916   }
3917 
3918   B->stencil.dim = A->stencil.dim;
3919   B->stencil.noc = A->stencil.noc;
3920   for (i=0; i<=A->stencil.dim; i++) {
3921     B->stencil.dims[i]   = A->stencil.dims[i];
3922     B->stencil.starts[i] = A->stencil.starts[i];
3923   }
3924 
3925   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3926   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3927   PetscFunctionReturn(0);
3928 }
3929 
3930 /*@C
3931    MatConvert - Converts a matrix to another matrix, either of the same
3932    or different type.
3933 
3934    Collective on Mat
3935 
3936    Input Parameters:
3937 +  mat - the matrix
3938 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3939    same type as the original matrix.
3940 -  reuse - denotes if the destination matrix is to be created or reused.
3941    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
3942    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).
3943 
3944    Output Parameter:
3945 .  M - pointer to place new matrix
3946 
3947    Notes:
3948    MatConvert() first creates a new matrix and then copies the data from
3949    the first matrix.  A related routine is MatCopy(), which copies the matrix
3950    entries of one matrix to another already existing matrix context.
3951 
3952    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3953    the MPI communicator of the generated matrix is always the same as the communicator
3954    of the input matrix.
3955 
3956    Level: intermediate
3957 
3958    Concepts: matrices^converting between storage formats
3959 
3960 .seealso: MatCopy(), MatDuplicate()
3961 @*/
3962 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3963 {
3964   PetscErrorCode ierr;
3965   PetscBool      sametype,issame,flg;
3966   char           convname[256],mtype[256];
3967   Mat            B;
3968 
3969   PetscFunctionBegin;
3970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3971   PetscValidType(mat,1);
3972   PetscValidPointer(M,3);
3973   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3974   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3975   MatCheckPreallocated(mat,1);
3976 
3977   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3978   if (flg) {
3979     newtype = mtype;
3980   }
3981   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3982   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3983   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3984   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");
3985 
3986   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3987 
3988   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3989     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3990   } else {
3991     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3992     const char     *prefix[3] = {"seq","mpi",""};
3993     PetscInt       i;
3994     /*
3995        Order of precedence:
3996        1) See if a specialized converter is known to the current matrix.
3997        2) See if a specialized converter is known to the desired matrix class.
3998        3) See if a good general converter is registered for the desired class
3999           (as of 6/27/03 only MATMPIADJ falls into this category).
4000        4) See if a good general converter is known for the current matrix.
4001        5) Use a really basic converter.
4002     */
4003 
4004     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4005     for (i=0; i<3; i++) {
4006       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4007       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4008       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4009       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4010       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4011       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4012       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4013       if (conv) goto foundconv;
4014     }
4015 
4016     /* 2)  See if a specialized converter is known to the desired matrix class. */
4017     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4018     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4019     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4020     for (i=0; i<3; i++) {
4021       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4022       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4023       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4024       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4025       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4026       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4027       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4028       if (conv) {
4029         ierr = MatDestroy(&B);CHKERRQ(ierr);
4030         goto foundconv;
4031       }
4032     }
4033 
4034     /* 3) See if a good general converter is registered for the desired class */
4035     conv = B->ops->convertfrom;
4036     ierr = MatDestroy(&B);CHKERRQ(ierr);
4037     if (conv) goto foundconv;
4038 
4039     /* 4) See if a good general converter is known for the current matrix */
4040     if (mat->ops->convert) {
4041       conv = mat->ops->convert;
4042     }
4043     if (conv) goto foundconv;
4044 
4045     /* 5) Use a really basic converter. */
4046     conv = MatConvert_Basic;
4047 
4048 foundconv:
4049     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4050     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4051     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4052       /* the block sizes must be same if the mappings are copied over */
4053       (*M)->rmap->bs = mat->rmap->bs;
4054       (*M)->cmap->bs = mat->cmap->bs;
4055       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4056       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4057       (*M)->rmap->mapping = mat->rmap->mapping;
4058       (*M)->cmap->mapping = mat->cmap->mapping;
4059     }
4060     (*M)->stencil.dim = mat->stencil.dim;
4061     (*M)->stencil.noc = mat->stencil.noc;
4062     for (i=0; i<=mat->stencil.dim; i++) {
4063       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4064       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4065     }
4066     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4067   }
4068   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4069 
4070   /* Copy Mat options */
4071   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4072   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4073   PetscFunctionReturn(0);
4074 }
4075 
4076 /*@C
4077    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4078 
4079    Not Collective
4080 
4081    Input Parameter:
4082 .  mat - the matrix, must be a factored matrix
4083 
4084    Output Parameter:
4085 .   type - the string name of the package (do not free this string)
4086 
4087    Notes:
4088       In Fortran you pass in a empty string and the package name will be copied into it.
4089     (Make sure the string is long enough)
4090 
4091    Level: intermediate
4092 
4093 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4094 @*/
4095 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4096 {
4097   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4098 
4099   PetscFunctionBegin;
4100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4101   PetscValidType(mat,1);
4102   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4103   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4104   if (!conv) {
4105     *type = MATSOLVERPETSC;
4106   } else {
4107     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4108   }
4109   PetscFunctionReturn(0);
4110 }
4111 
4112 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4113 struct _MatSolverTypeForSpecifcType {
4114   MatType                        mtype;
4115   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4116   MatSolverTypeForSpecifcType next;
4117 };
4118 
4119 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4120 struct _MatSolverTypeHolder {
4121   char                           *name;
4122   MatSolverTypeForSpecifcType handlers;
4123   MatSolverTypeHolder         next;
4124 };
4125 
4126 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4127 
4128 /*@C
4129    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4130 
4131    Input Parameters:
4132 +    package - name of the package, for example petsc or superlu
4133 .    mtype - the matrix type that works with this package
4134 .    ftype - the type of factorization supported by the package
4135 -    getfactor - routine that will create the factored matrix ready to be used
4136 
4137     Level: intermediate
4138 
4139 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4140 @*/
4141 PetscErrorCode MatSolverTypeRegister(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4142 {
4143   PetscErrorCode              ierr;
4144   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4145   PetscBool                   flg;
4146   MatSolverTypeForSpecifcType inext,iprev = NULL;
4147 
4148   PetscFunctionBegin;
4149   if (!next) {
4150     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4151     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4152     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4153     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4154     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4155     PetscFunctionReturn(0);
4156   }
4157   while (next) {
4158     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4159     if (flg) {
4160       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4161       inext = next->handlers;
4162       while (inext) {
4163         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4164         if (flg) {
4165           inext->getfactor[(int)ftype-1] = getfactor;
4166           PetscFunctionReturn(0);
4167         }
4168         iprev = inext;
4169         inext = inext->next;
4170       }
4171       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4172       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4173       iprev->next->getfactor[(int)ftype-1] = getfactor;
4174       PetscFunctionReturn(0);
4175     }
4176     prev = next;
4177     next = next->next;
4178   }
4179   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4180   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4181   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4182   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4183   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4184   PetscFunctionReturn(0);
4185 }
4186 
4187 /*@C
4188    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4189 
4190    Input Parameters:
4191 +    package - name of the package, for example petsc or superlu
4192 .    ftype - the type of factorization supported by the package
4193 -    mtype - the matrix type that works with this package
4194 
4195    Output Parameters:
4196 +   foundpackage - PETSC_TRUE if the package was registered
4197 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4198 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4199 
4200     Level: intermediate
4201 
4202 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4203 @*/
4204 PetscErrorCode MatSolverTypeGet(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4205 {
4206   PetscErrorCode                 ierr;
4207   MatSolverTypeHolder         next = MatSolverTypeHolders;
4208   PetscBool                      flg;
4209   MatSolverTypeForSpecifcType inext;
4210 
4211   PetscFunctionBegin;
4212   if (foundpackage) *foundpackage = PETSC_FALSE;
4213   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4214   if (getfactor)    *getfactor    = NULL;
4215 
4216   if (package) {
4217     while (next) {
4218       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4219       if (flg) {
4220         if (foundpackage) *foundpackage = PETSC_TRUE;
4221         inext = next->handlers;
4222         while (inext) {
4223           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4224           if (flg) {
4225             if (foundmtype) *foundmtype = PETSC_TRUE;
4226             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4227             PetscFunctionReturn(0);
4228           }
4229           inext = inext->next;
4230         }
4231       }
4232       next = next->next;
4233     }
4234   } else {
4235     while (next) {
4236       inext = next->handlers;
4237       while (inext) {
4238         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4239         if (flg && inext->getfactor[(int)ftype-1]) {
4240           if (foundpackage) *foundpackage = PETSC_TRUE;
4241           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4242           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4243           PetscFunctionReturn(0);
4244         }
4245         inext = inext->next;
4246       }
4247       next = next->next;
4248     }
4249   }
4250   PetscFunctionReturn(0);
4251 }
4252 
4253 PetscErrorCode MatSolverTypeDestroy(void)
4254 {
4255   PetscErrorCode              ierr;
4256   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4257   MatSolverTypeForSpecifcType inext,iprev;
4258 
4259   PetscFunctionBegin;
4260   while (next) {
4261     ierr = PetscFree(next->name);CHKERRQ(ierr);
4262     inext = next->handlers;
4263     while (inext) {
4264       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4265       iprev = inext;
4266       inext = inext->next;
4267       ierr = PetscFree(iprev);CHKERRQ(ierr);
4268     }
4269     prev = next;
4270     next = next->next;
4271     ierr = PetscFree(prev);CHKERRQ(ierr);
4272   }
4273   MatSolverTypeHolders = NULL;
4274   PetscFunctionReturn(0);
4275 }
4276 
4277 /*@C
4278    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4279 
4280    Collective on Mat
4281 
4282    Input Parameters:
4283 +  mat - the matrix
4284 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4285 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4286 
4287    Output Parameters:
4288 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4289 
4290    Notes:
4291       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4292      such as pastix, superlu, mumps etc.
4293 
4294       PETSc must have been ./configure to use the external solver, using the option --download-package
4295 
4296    Level: intermediate
4297 
4298 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4299 @*/
4300 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4301 {
4302   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4303   PetscBool      foundpackage,foundmtype;
4304 
4305   PetscFunctionBegin;
4306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4307   PetscValidType(mat,1);
4308 
4309   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4310   MatCheckPreallocated(mat,1);
4311 
4312   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4313   if (!foundpackage) {
4314     if (type) {
4315       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4316     } else {
4317       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4318     }
4319   }
4320 
4321   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4322   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);
4323 
4324 #if defined(PETSC_USE_COMPLEX)
4325   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");
4326 #endif
4327 
4328   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4329   PetscFunctionReturn(0);
4330 }
4331 
4332 /*@C
4333    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4334 
4335    Not Collective
4336 
4337    Input Parameters:
4338 +  mat - the matrix
4339 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4340 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4341 
4342    Output Parameter:
4343 .    flg - PETSC_TRUE if the factorization is available
4344 
4345    Notes:
4346       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4347      such as pastix, superlu, mumps etc.
4348 
4349       PETSc must have been ./configure to use the external solver, using the option --download-package
4350 
4351    Level: intermediate
4352 
4353 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4354 @*/
4355 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4356 {
4357   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4358 
4359   PetscFunctionBegin;
4360   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4361   PetscValidType(mat,1);
4362 
4363   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4364   MatCheckPreallocated(mat,1);
4365 
4366   *flg = PETSC_FALSE;
4367   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4368   if (gconv) {
4369     *flg = PETSC_TRUE;
4370   }
4371   PetscFunctionReturn(0);
4372 }
4373 
4374 #include <petscdmtypes.h>
4375 
4376 /*@
4377    MatDuplicate - Duplicates a matrix including the non-zero structure.
4378 
4379    Collective on Mat
4380 
4381    Input Parameters:
4382 +  mat - the matrix
4383 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4384         See the manual page for MatDuplicateOption for an explanation of these options.
4385 
4386    Output Parameter:
4387 .  M - pointer to place new matrix
4388 
4389    Level: intermediate
4390 
4391    Concepts: matrices^duplicating
4392 
4393    Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4394 
4395 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4396 @*/
4397 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4398 {
4399   PetscErrorCode ierr;
4400   Mat            B;
4401   PetscInt       i;
4402   DM             dm;
4403 
4404   PetscFunctionBegin;
4405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4406   PetscValidType(mat,1);
4407   PetscValidPointer(M,3);
4408   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4409   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4410   MatCheckPreallocated(mat,1);
4411 
4412   *M = 0;
4413   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4414   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4415   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4416   B    = *M;
4417 
4418   B->stencil.dim = mat->stencil.dim;
4419   B->stencil.noc = mat->stencil.noc;
4420   for (i=0; i<=mat->stencil.dim; i++) {
4421     B->stencil.dims[i]   = mat->stencil.dims[i];
4422     B->stencil.starts[i] = mat->stencil.starts[i];
4423   }
4424 
4425   B->nooffproczerorows = mat->nooffproczerorows;
4426   B->nooffprocentries  = mat->nooffprocentries;
4427 
4428   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4429   if (dm) {
4430     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4431   }
4432   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4433   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4434   PetscFunctionReturn(0);
4435 }
4436 
4437 /*@
4438    MatGetDiagonal - Gets the diagonal of a matrix.
4439 
4440    Logically Collective on Mat and Vec
4441 
4442    Input Parameters:
4443 +  mat - the matrix
4444 -  v - the vector for storing the diagonal
4445 
4446    Output Parameter:
4447 .  v - the diagonal of the matrix
4448 
4449    Level: intermediate
4450 
4451    Note:
4452    Currently only correct in parallel for square matrices.
4453 
4454    Concepts: matrices^accessing diagonals
4455 
4456 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4457 @*/
4458 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4459 {
4460   PetscErrorCode ierr;
4461 
4462   PetscFunctionBegin;
4463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4464   PetscValidType(mat,1);
4465   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4466   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4467   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4468   MatCheckPreallocated(mat,1);
4469 
4470   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4471   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4472   PetscFunctionReturn(0);
4473 }
4474 
4475 /*@C
4476    MatGetRowMin - Gets the minimum value (of the real part) of each
4477         row of the matrix
4478 
4479    Logically Collective on Mat and Vec
4480 
4481    Input Parameters:
4482 .  mat - the matrix
4483 
4484    Output Parameter:
4485 +  v - the vector for storing the maximums
4486 -  idx - the indices of the column found for each row (optional)
4487 
4488    Level: intermediate
4489 
4490    Notes: The result of this call are the same as if one converted the matrix to dense format
4491       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4492 
4493     This code is only implemented for a couple of matrix formats.
4494 
4495    Concepts: matrices^getting row maximums
4496 
4497 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4498           MatGetRowMax()
4499 @*/
4500 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4501 {
4502   PetscErrorCode ierr;
4503 
4504   PetscFunctionBegin;
4505   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4506   PetscValidType(mat,1);
4507   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4508   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4509   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4510   MatCheckPreallocated(mat,1);
4511 
4512   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4513   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4514   PetscFunctionReturn(0);
4515 }
4516 
4517 /*@C
4518    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4519         row of the matrix
4520 
4521    Logically Collective on Mat and Vec
4522 
4523    Input Parameters:
4524 .  mat - the matrix
4525 
4526    Output Parameter:
4527 +  v - the vector for storing the minimums
4528 -  idx - the indices of the column found for each row (or NULL if not needed)
4529 
4530    Level: intermediate
4531 
4532    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4533     row is 0 (the first column).
4534 
4535     This code is only implemented for a couple of matrix formats.
4536 
4537    Concepts: matrices^getting row maximums
4538 
4539 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4540 @*/
4541 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4542 {
4543   PetscErrorCode ierr;
4544 
4545   PetscFunctionBegin;
4546   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4547   PetscValidType(mat,1);
4548   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4549   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4550   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4551   MatCheckPreallocated(mat,1);
4552   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4553 
4554   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4555   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4556   PetscFunctionReturn(0);
4557 }
4558 
4559 /*@C
4560    MatGetRowMax - Gets the maximum value (of the real part) of each
4561         row of the matrix
4562 
4563    Logically Collective on Mat and Vec
4564 
4565    Input Parameters:
4566 .  mat - the matrix
4567 
4568    Output Parameter:
4569 +  v - the vector for storing the maximums
4570 -  idx - the indices of the column found for each row (optional)
4571 
4572    Level: intermediate
4573 
4574    Notes: The result of this call are the same as if one converted the matrix to dense format
4575       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4576 
4577     This code is only implemented for a couple of matrix formats.
4578 
4579    Concepts: matrices^getting row maximums
4580 
4581 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4582 @*/
4583 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4584 {
4585   PetscErrorCode ierr;
4586 
4587   PetscFunctionBegin;
4588   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4589   PetscValidType(mat,1);
4590   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4591   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4592   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4593   MatCheckPreallocated(mat,1);
4594 
4595   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4596   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4597   PetscFunctionReturn(0);
4598 }
4599 
4600 /*@C
4601    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4602         row of the matrix
4603 
4604    Logically Collective on Mat and Vec
4605 
4606    Input Parameters:
4607 .  mat - the matrix
4608 
4609    Output Parameter:
4610 +  v - the vector for storing the maximums
4611 -  idx - the indices of the column found for each row (or NULL if not needed)
4612 
4613    Level: intermediate
4614 
4615    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4616     row is 0 (the first column).
4617 
4618     This code is only implemented for a couple of matrix formats.
4619 
4620    Concepts: matrices^getting row maximums
4621 
4622 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4623 @*/
4624 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4625 {
4626   PetscErrorCode ierr;
4627 
4628   PetscFunctionBegin;
4629   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4630   PetscValidType(mat,1);
4631   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4632   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4633   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4634   MatCheckPreallocated(mat,1);
4635   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4636 
4637   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4638   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4639   PetscFunctionReturn(0);
4640 }
4641 
4642 /*@
4643    MatGetRowSum - Gets the sum of each row of the matrix
4644 
4645    Logically or Neighborhood Collective on Mat and Vec
4646 
4647    Input Parameters:
4648 .  mat - the matrix
4649 
4650    Output Parameter:
4651 .  v - the vector for storing the sum of rows
4652 
4653    Level: intermediate
4654 
4655    Notes: This code is slow since it is not currently specialized for different formats
4656 
4657    Concepts: matrices^getting row sums
4658 
4659 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4660 @*/
4661 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4662 {
4663   Vec            ones;
4664   PetscErrorCode ierr;
4665 
4666   PetscFunctionBegin;
4667   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4668   PetscValidType(mat,1);
4669   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4670   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4671   MatCheckPreallocated(mat,1);
4672   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4673   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4674   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4675   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4676   PetscFunctionReturn(0);
4677 }
4678 
4679 /*@
4680    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4681 
4682    Collective on Mat
4683 
4684    Input Parameter:
4685 +  mat - the matrix to transpose
4686 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4687 
4688    Output Parameters:
4689 .  B - the transpose
4690 
4691    Notes:
4692      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4693 
4694      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4695 
4696      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4697 
4698    Level: intermediate
4699 
4700    Concepts: matrices^transposing
4701 
4702 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4703 @*/
4704 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4705 {
4706   PetscErrorCode ierr;
4707 
4708   PetscFunctionBegin;
4709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4710   PetscValidType(mat,1);
4711   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4712   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4713   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4714   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4715   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4716   MatCheckPreallocated(mat,1);
4717 
4718   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4719   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4720   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4721   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4722   PetscFunctionReturn(0);
4723 }
4724 
4725 /*@
4726    MatIsTranspose - Test whether a matrix is another one's transpose,
4727         or its own, in which case it tests symmetry.
4728 
4729    Collective on Mat
4730 
4731    Input Parameter:
4732 +  A - the matrix to test
4733 -  B - the matrix to test against, this can equal the first parameter
4734 
4735    Output Parameters:
4736 .  flg - the result
4737 
4738    Notes:
4739    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4740    has a running time of the order of the number of nonzeros; the parallel
4741    test involves parallel copies of the block-offdiagonal parts of the matrix.
4742 
4743    Level: intermediate
4744 
4745    Concepts: matrices^transposing, matrix^symmetry
4746 
4747 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4748 @*/
4749 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4750 {
4751   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4752 
4753   PetscFunctionBegin;
4754   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4755   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4756   PetscValidPointer(flg,3);
4757   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4758   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4759   *flg = PETSC_FALSE;
4760   if (f && g) {
4761     if (f == g) {
4762       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4763     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4764   } else {
4765     MatType mattype;
4766     if (!f) {
4767       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4768     } else {
4769       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4770     }
4771     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4772   }
4773   PetscFunctionReturn(0);
4774 }
4775 
4776 /*@
4777    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4778 
4779    Collective on Mat
4780 
4781    Input Parameter:
4782 +  mat - the matrix to transpose and complex conjugate
4783 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4784 
4785    Output Parameters:
4786 .  B - the Hermitian
4787 
4788    Level: intermediate
4789 
4790    Concepts: matrices^transposing, complex conjugatex
4791 
4792 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4793 @*/
4794 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4795 {
4796   PetscErrorCode ierr;
4797 
4798   PetscFunctionBegin;
4799   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4800 #if defined(PETSC_USE_COMPLEX)
4801   ierr = MatConjugate(*B);CHKERRQ(ierr);
4802 #endif
4803   PetscFunctionReturn(0);
4804 }
4805 
4806 /*@
4807    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4808 
4809    Collective on Mat
4810 
4811    Input Parameter:
4812 +  A - the matrix to test
4813 -  B - the matrix to test against, this can equal the first parameter
4814 
4815    Output Parameters:
4816 .  flg - the result
4817 
4818    Notes:
4819    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4820    has a running time of the order of the number of nonzeros; the parallel
4821    test involves parallel copies of the block-offdiagonal parts of the matrix.
4822 
4823    Level: intermediate
4824 
4825    Concepts: matrices^transposing, matrix^symmetry
4826 
4827 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4828 @*/
4829 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4830 {
4831   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4832 
4833   PetscFunctionBegin;
4834   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4835   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4836   PetscValidPointer(flg,3);
4837   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4838   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4839   if (f && g) {
4840     if (f==g) {
4841       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4842     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4843   }
4844   PetscFunctionReturn(0);
4845 }
4846 
4847 /*@
4848    MatPermute - Creates a new matrix with rows and columns permuted from the
4849    original.
4850 
4851    Collective on Mat
4852 
4853    Input Parameters:
4854 +  mat - the matrix to permute
4855 .  row - row permutation, each processor supplies only the permutation for its rows
4856 -  col - column permutation, each processor supplies only the permutation for its columns
4857 
4858    Output Parameters:
4859 .  B - the permuted matrix
4860 
4861    Level: advanced
4862 
4863    Note:
4864    The index sets map from row/col of permuted matrix to row/col of original matrix.
4865    The index sets should be on the same communicator as Mat and have the same local sizes.
4866 
4867    Concepts: matrices^permuting
4868 
4869 .seealso: MatGetOrdering(), ISAllGather()
4870 
4871 @*/
4872 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4873 {
4874   PetscErrorCode ierr;
4875 
4876   PetscFunctionBegin;
4877   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4878   PetscValidType(mat,1);
4879   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4880   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4881   PetscValidPointer(B,4);
4882   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4883   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4884   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4885   MatCheckPreallocated(mat,1);
4886 
4887   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4888   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4889   PetscFunctionReturn(0);
4890 }
4891 
4892 /*@
4893    MatEqual - Compares two matrices.
4894 
4895    Collective on Mat
4896 
4897    Input Parameters:
4898 +  A - the first matrix
4899 -  B - the second matrix
4900 
4901    Output Parameter:
4902 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4903 
4904    Level: intermediate
4905 
4906    Concepts: matrices^equality between
4907 @*/
4908 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4909 {
4910   PetscErrorCode ierr;
4911 
4912   PetscFunctionBegin;
4913   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4914   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4915   PetscValidType(A,1);
4916   PetscValidType(B,2);
4917   PetscValidIntPointer(flg,3);
4918   PetscCheckSameComm(A,1,B,2);
4919   MatCheckPreallocated(B,2);
4920   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4921   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4922   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);
4923   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4924   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4925   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);
4926   MatCheckPreallocated(A,1);
4927 
4928   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4929   PetscFunctionReturn(0);
4930 }
4931 
4932 /*@C
4933    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4934    matrices that are stored as vectors.  Either of the two scaling
4935    matrices can be NULL.
4936 
4937    Collective on Mat
4938 
4939    Input Parameters:
4940 +  mat - the matrix to be scaled
4941 .  l - the left scaling vector (or NULL)
4942 -  r - the right scaling vector (or NULL)
4943 
4944    Notes:
4945    MatDiagonalScale() computes A = LAR, where
4946    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4947    The L scales the rows of the matrix, the R scales the columns of the matrix.
4948 
4949    Level: intermediate
4950 
4951    Concepts: matrices^diagonal scaling
4952    Concepts: diagonal scaling of matrices
4953 
4954 .seealso: MatScale(), MatShift(), MatDiagonalSet()
4955 @*/
4956 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4957 {
4958   PetscErrorCode ierr;
4959 
4960   PetscFunctionBegin;
4961   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4962   PetscValidType(mat,1);
4963   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4964   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4965   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4966   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4967   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4968   MatCheckPreallocated(mat,1);
4969 
4970   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4971   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4972   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4973   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4974 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
4975   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
4976     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
4977   }
4978 #endif
4979   PetscFunctionReturn(0);
4980 }
4981 
4982 /*@
4983     MatScale - Scales all elements of a matrix by a given number.
4984 
4985     Logically Collective on Mat
4986 
4987     Input Parameters:
4988 +   mat - the matrix to be scaled
4989 -   a  - the scaling value
4990 
4991     Output Parameter:
4992 .   mat - the scaled matrix
4993 
4994     Level: intermediate
4995 
4996     Concepts: matrices^scaling all entries
4997 
4998 .seealso: MatDiagonalScale()
4999 @*/
5000 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5001 {
5002   PetscErrorCode ierr;
5003 
5004   PetscFunctionBegin;
5005   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5006   PetscValidType(mat,1);
5007   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5008   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5009   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5010   PetscValidLogicalCollectiveScalar(mat,a,2);
5011   MatCheckPreallocated(mat,1);
5012 
5013   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5014   if (a != (PetscScalar)1.0) {
5015     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5016     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5017 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5018     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5019       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5020     }
5021 #endif
5022   }
5023   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5024   PetscFunctionReturn(0);
5025 }
5026 
5027 /*@
5028    MatNorm - Calculates various norms of a matrix.
5029 
5030    Collective on Mat
5031 
5032    Input Parameters:
5033 +  mat - the matrix
5034 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5035 
5036    Output Parameters:
5037 .  nrm - the resulting norm
5038 
5039    Level: intermediate
5040 
5041    Concepts: matrices^norm
5042    Concepts: norm^of matrix
5043 @*/
5044 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5045 {
5046   PetscErrorCode ierr;
5047 
5048   PetscFunctionBegin;
5049   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5050   PetscValidType(mat,1);
5051   PetscValidScalarPointer(nrm,3);
5052 
5053   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5054   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5055   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5056   MatCheckPreallocated(mat,1);
5057 
5058   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5059   PetscFunctionReturn(0);
5060 }
5061 
5062 /*
5063      This variable is used to prevent counting of MatAssemblyBegin() that
5064    are called from within a MatAssemblyEnd().
5065 */
5066 static PetscInt MatAssemblyEnd_InUse = 0;
5067 /*@
5068    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5069    be called after completing all calls to MatSetValues().
5070 
5071    Collective on Mat
5072 
5073    Input Parameters:
5074 +  mat - the matrix
5075 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5076 
5077    Notes:
5078    MatSetValues() generally caches the values.  The matrix is ready to
5079    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5080    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5081    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5082    using the matrix.
5083 
5084    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5085    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
5086    a global collective operation requring all processes that share the matrix.
5087 
5088    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5089    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5090    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5091 
5092    Level: beginner
5093 
5094    Concepts: matrices^assembling
5095 
5096 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5097 @*/
5098 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5099 {
5100   PetscErrorCode ierr;
5101 
5102   PetscFunctionBegin;
5103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5104   PetscValidType(mat,1);
5105   MatCheckPreallocated(mat,1);
5106   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5107   if (mat->assembled) {
5108     mat->was_assembled = PETSC_TRUE;
5109     mat->assembled     = PETSC_FALSE;
5110   }
5111   if (!MatAssemblyEnd_InUse) {
5112     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5113     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5114     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5115   } else if (mat->ops->assemblybegin) {
5116     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5117   }
5118   PetscFunctionReturn(0);
5119 }
5120 
5121 /*@
5122    MatAssembled - Indicates if a matrix has been assembled and is ready for
5123      use; for example, in matrix-vector product.
5124 
5125    Not Collective
5126 
5127    Input Parameter:
5128 .  mat - the matrix
5129 
5130    Output Parameter:
5131 .  assembled - PETSC_TRUE or PETSC_FALSE
5132 
5133    Level: advanced
5134 
5135    Concepts: matrices^assembled?
5136 
5137 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5138 @*/
5139 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5140 {
5141   PetscFunctionBegin;
5142   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5143   PetscValidType(mat,1);
5144   PetscValidPointer(assembled,2);
5145   *assembled = mat->assembled;
5146   PetscFunctionReturn(0);
5147 }
5148 
5149 /*@
5150    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5151    be called after MatAssemblyBegin().
5152 
5153    Collective on Mat
5154 
5155    Input Parameters:
5156 +  mat - the matrix
5157 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5158 
5159    Options Database Keys:
5160 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5161 .  -mat_view ::ascii_info_detail - Prints more detailed info
5162 .  -mat_view - Prints matrix in ASCII format
5163 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5164 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5165 .  -display <name> - Sets display name (default is host)
5166 .  -draw_pause <sec> - Sets number of seconds to pause after display
5167 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5168 .  -viewer_socket_machine <machine> - Machine to use for socket
5169 .  -viewer_socket_port <port> - Port number to use for socket
5170 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5171 
5172    Notes:
5173    MatSetValues() generally caches the values.  The matrix is ready to
5174    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5175    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5176    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5177    using the matrix.
5178 
5179    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5180    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5181    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5182 
5183    Level: beginner
5184 
5185 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5186 @*/
5187 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5188 {
5189   PetscErrorCode  ierr;
5190   static PetscInt inassm = 0;
5191   PetscBool       flg    = PETSC_FALSE;
5192 
5193   PetscFunctionBegin;
5194   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5195   PetscValidType(mat,1);
5196 
5197   inassm++;
5198   MatAssemblyEnd_InUse++;
5199   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5200     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5201     if (mat->ops->assemblyend) {
5202       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5203     }
5204     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5205   } else if (mat->ops->assemblyend) {
5206     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5207   }
5208 
5209   /* Flush assembly is not a true assembly */
5210   if (type != MAT_FLUSH_ASSEMBLY) {
5211     mat->assembled = PETSC_TRUE; mat->num_ass++;
5212   }
5213   mat->insertmode = NOT_SET_VALUES;
5214   MatAssemblyEnd_InUse--;
5215   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5216   if (!mat->symmetric_eternal) {
5217     mat->symmetric_set              = PETSC_FALSE;
5218     mat->hermitian_set              = PETSC_FALSE;
5219     mat->structurally_symmetric_set = PETSC_FALSE;
5220   }
5221 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5222   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5223     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5224   }
5225 #endif
5226   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5227     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5228 
5229     if (mat->checksymmetryonassembly) {
5230       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5231       if (flg) {
5232         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5233       } else {
5234         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5235       }
5236     }
5237     if (mat->nullsp && mat->checknullspaceonassembly) {
5238       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5239     }
5240   }
5241   inassm--;
5242   PetscFunctionReturn(0);
5243 }
5244 
5245 /*@
5246    MatSetOption - Sets a parameter option for a matrix. Some options
5247    may be specific to certain storage formats.  Some options
5248    determine how values will be inserted (or added). Sorted,
5249    row-oriented input will generally assemble the fastest. The default
5250    is row-oriented.
5251 
5252    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5253 
5254    Input Parameters:
5255 +  mat - the matrix
5256 .  option - the option, one of those listed below (and possibly others),
5257 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5258 
5259   Options Describing Matrix Structure:
5260 +    MAT_SPD - symmetric positive definite
5261 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5262 .    MAT_HERMITIAN - transpose is the complex conjugation
5263 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5264 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5265                             you set to be kept with all future use of the matrix
5266                             including after MatAssemblyBegin/End() which could
5267                             potentially change the symmetry structure, i.e. you
5268                             KNOW the matrix will ALWAYS have the property you set.
5269 
5270 
5271    Options For Use with MatSetValues():
5272    Insert a logically dense subblock, which can be
5273 .    MAT_ROW_ORIENTED - row-oriented (default)
5274 
5275    Note these options reflect the data you pass in with MatSetValues(); it has
5276    nothing to do with how the data is stored internally in the matrix
5277    data structure.
5278 
5279    When (re)assembling a matrix, we can restrict the input for
5280    efficiency/debugging purposes.  These options include:
5281 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5282 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5283 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5284 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5285 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5286 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5287         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5288         performance for very large process counts.
5289 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5290         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5291         functions, instead sending only neighbor messages.
5292 
5293    Notes:
5294    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5295 
5296    Some options are relevant only for particular matrix types and
5297    are thus ignored by others.  Other options are not supported by
5298    certain matrix types and will generate an error message if set.
5299 
5300    If using a Fortran 77 module to compute a matrix, one may need to
5301    use the column-oriented option (or convert to the row-oriented
5302    format).
5303 
5304    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5305    that would generate a new entry in the nonzero structure is instead
5306    ignored.  Thus, if memory has not alredy been allocated for this particular
5307    data, then the insertion is ignored. For dense matrices, in which
5308    the entire array is allocated, no entries are ever ignored.
5309    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5310 
5311    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5312    that would generate a new entry in the nonzero structure instead produces
5313    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
5314 
5315    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5316    that would generate a new entry that has not been preallocated will
5317    instead produce an error. (Currently supported for AIJ and BAIJ formats
5318    only.) This is a useful flag when debugging matrix memory preallocation.
5319    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5320 
5321    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5322    other processors should be dropped, rather than stashed.
5323    This is useful if you know that the "owning" processor is also
5324    always generating the correct matrix entries, so that PETSc need
5325    not transfer duplicate entries generated on another processor.
5326 
5327    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5328    searches during matrix assembly. When this flag is set, the hash table
5329    is created during the first Matrix Assembly. This hash table is
5330    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5331    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5332    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5333    supported by MATMPIBAIJ format only.
5334 
5335    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5336    are kept in the nonzero structure
5337 
5338    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5339    a zero location in the matrix
5340 
5341    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5342 
5343    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5344         zero row routines and thus improves performance for very large process counts.
5345 
5346    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5347         part of the matrix (since they should match the upper triangular part).
5348 
5349    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5350 
5351    Level: intermediate
5352 
5353    Concepts: matrices^setting options
5354 
5355 .seealso:  MatOption, Mat
5356 
5357 @*/
5358 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5359 {
5360   PetscErrorCode ierr;
5361 
5362   PetscFunctionBegin;
5363   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5364   PetscValidType(mat,1);
5365   if (op > 0) {
5366     PetscValidLogicalCollectiveEnum(mat,op,2);
5367     PetscValidLogicalCollectiveBool(mat,flg,3);
5368   }
5369 
5370   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);
5371   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()");
5372 
5373   switch (op) {
5374   case MAT_NO_OFF_PROC_ENTRIES:
5375     mat->nooffprocentries = flg;
5376     PetscFunctionReturn(0);
5377     break;
5378   case MAT_SUBSET_OFF_PROC_ENTRIES:
5379     mat->subsetoffprocentries = flg;
5380     PetscFunctionReturn(0);
5381   case MAT_NO_OFF_PROC_ZERO_ROWS:
5382     mat->nooffproczerorows = flg;
5383     PetscFunctionReturn(0);
5384     break;
5385   case MAT_SPD:
5386     mat->spd_set = PETSC_TRUE;
5387     mat->spd     = flg;
5388     if (flg) {
5389       mat->symmetric                  = PETSC_TRUE;
5390       mat->structurally_symmetric     = PETSC_TRUE;
5391       mat->symmetric_set              = PETSC_TRUE;
5392       mat->structurally_symmetric_set = PETSC_TRUE;
5393     }
5394     break;
5395   case MAT_SYMMETRIC:
5396     mat->symmetric = flg;
5397     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5398     mat->symmetric_set              = PETSC_TRUE;
5399     mat->structurally_symmetric_set = flg;
5400 #if !defined(PETSC_USE_COMPLEX)
5401     mat->hermitian     = flg;
5402     mat->hermitian_set = PETSC_TRUE;
5403 #endif
5404     break;
5405   case MAT_HERMITIAN:
5406     mat->hermitian = flg;
5407     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5408     mat->hermitian_set              = PETSC_TRUE;
5409     mat->structurally_symmetric_set = flg;
5410 #if !defined(PETSC_USE_COMPLEX)
5411     mat->symmetric     = flg;
5412     mat->symmetric_set = PETSC_TRUE;
5413 #endif
5414     break;
5415   case MAT_STRUCTURALLY_SYMMETRIC:
5416     mat->structurally_symmetric     = flg;
5417     mat->structurally_symmetric_set = PETSC_TRUE;
5418     break;
5419   case MAT_SYMMETRY_ETERNAL:
5420     mat->symmetric_eternal = flg;
5421     break;
5422   case MAT_STRUCTURE_ONLY:
5423     mat->structure_only = flg;
5424     break;
5425   default:
5426     break;
5427   }
5428   if (mat->ops->setoption) {
5429     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5430   }
5431   PetscFunctionReturn(0);
5432 }
5433 
5434 /*@
5435    MatGetOption - Gets a parameter option that has been set for a matrix.
5436 
5437    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5438 
5439    Input Parameters:
5440 +  mat - the matrix
5441 -  option - the option, this only responds to certain options, check the code for which ones
5442 
5443    Output Parameter:
5444 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5445 
5446     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5447 
5448    Level: intermediate
5449 
5450    Concepts: matrices^setting options
5451 
5452 .seealso:  MatOption, MatSetOption()
5453 
5454 @*/
5455 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5456 {
5457   PetscFunctionBegin;
5458   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5459   PetscValidType(mat,1);
5460 
5461   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);
5462   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()");
5463 
5464   switch (op) {
5465   case MAT_NO_OFF_PROC_ENTRIES:
5466     *flg = mat->nooffprocentries;
5467     break;
5468   case MAT_NO_OFF_PROC_ZERO_ROWS:
5469     *flg = mat->nooffproczerorows;
5470     break;
5471   case MAT_SYMMETRIC:
5472     *flg = mat->symmetric;
5473     break;
5474   case MAT_HERMITIAN:
5475     *flg = mat->hermitian;
5476     break;
5477   case MAT_STRUCTURALLY_SYMMETRIC:
5478     *flg = mat->structurally_symmetric;
5479     break;
5480   case MAT_SYMMETRY_ETERNAL:
5481     *flg = mat->symmetric_eternal;
5482     break;
5483   case MAT_SPD:
5484     *flg = mat->spd;
5485     break;
5486   default:
5487     break;
5488   }
5489   PetscFunctionReturn(0);
5490 }
5491 
5492 /*@
5493    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5494    this routine retains the old nonzero structure.
5495 
5496    Logically Collective on Mat
5497 
5498    Input Parameters:
5499 .  mat - the matrix
5500 
5501    Level: intermediate
5502 
5503    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.
5504    See the Performance chapter of the users manual for information on preallocating matrices.
5505 
5506    Concepts: matrices^zeroing
5507 
5508 .seealso: MatZeroRows()
5509 @*/
5510 PetscErrorCode MatZeroEntries(Mat mat)
5511 {
5512   PetscErrorCode ierr;
5513 
5514   PetscFunctionBegin;
5515   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5516   PetscValidType(mat,1);
5517   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5518   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");
5519   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5520   MatCheckPreallocated(mat,1);
5521 
5522   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5523   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5524   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5525   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5526 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5527   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5528     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5529   }
5530 #endif
5531   PetscFunctionReturn(0);
5532 }
5533 
5534 /*@C
5535    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5536    of a set of rows and columns of a matrix.
5537 
5538    Collective on Mat
5539 
5540    Input Parameters:
5541 +  mat - the matrix
5542 .  numRows - the number of rows to remove
5543 .  rows - the global row indices
5544 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5545 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5546 -  b - optional vector of right hand side, that will be adjusted by provided solution
5547 
5548    Notes:
5549    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5550 
5551    The user can set a value in the diagonal entry (or for the AIJ and
5552    row formats can optionally remove the main diagonal entry from the
5553    nonzero structure as well, by passing 0.0 as the final argument).
5554 
5555    For the parallel case, all processes that share the matrix (i.e.,
5556    those in the communicator used for matrix creation) MUST call this
5557    routine, regardless of whether any rows being zeroed are owned by
5558    them.
5559 
5560    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5561    list only rows local to itself).
5562 
5563    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5564 
5565    Level: intermediate
5566 
5567    Concepts: matrices^zeroing rows
5568 
5569 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5570           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5571 @*/
5572 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5573 {
5574   PetscErrorCode ierr;
5575 
5576   PetscFunctionBegin;
5577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5578   PetscValidType(mat,1);
5579   if (numRows) PetscValidIntPointer(rows,3);
5580   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5581   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5582   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5583   MatCheckPreallocated(mat,1);
5584 
5585   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5586   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5587   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5588 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5589   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5590     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5591   }
5592 #endif
5593   PetscFunctionReturn(0);
5594 }
5595 
5596 /*@C
5597    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5598    of a set of rows and columns of a matrix.
5599 
5600    Collective on Mat
5601 
5602    Input Parameters:
5603 +  mat - the matrix
5604 .  is - the rows to zero
5605 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5606 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5607 -  b - optional vector of right hand side, that will be adjusted by provided solution
5608 
5609    Notes:
5610    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5611 
5612    The user can set a value in the diagonal entry (or for the AIJ and
5613    row formats can optionally remove the main diagonal entry from the
5614    nonzero structure as well, by passing 0.0 as the final argument).
5615 
5616    For the parallel case, all processes that share the matrix (i.e.,
5617    those in the communicator used for matrix creation) MUST call this
5618    routine, regardless of whether any rows being zeroed are owned by
5619    them.
5620 
5621    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5622    list only rows local to itself).
5623 
5624    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5625 
5626    Level: intermediate
5627 
5628    Concepts: matrices^zeroing rows
5629 
5630 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5631           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5632 @*/
5633 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5634 {
5635   PetscErrorCode ierr;
5636   PetscInt       numRows;
5637   const PetscInt *rows;
5638 
5639   PetscFunctionBegin;
5640   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5641   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5642   PetscValidType(mat,1);
5643   PetscValidType(is,2);
5644   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5645   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5646   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5647   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5648   PetscFunctionReturn(0);
5649 }
5650 
5651 /*@C
5652    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5653    of a set of rows of a matrix.
5654 
5655    Collective on Mat
5656 
5657    Input Parameters:
5658 +  mat - the matrix
5659 .  numRows - the number of rows to remove
5660 .  rows - the global row indices
5661 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5662 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5663 -  b - optional vector of right hand side, that will be adjusted by provided solution
5664 
5665    Notes:
5666    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5667    but does not release memory.  For the dense and block diagonal
5668    formats this does not alter the nonzero structure.
5669 
5670    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5671    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5672    merely zeroed.
5673 
5674    The user can set a value in the diagonal entry (or for the AIJ and
5675    row formats can optionally remove the main diagonal entry from the
5676    nonzero structure as well, by passing 0.0 as the final argument).
5677 
5678    For the parallel case, all processes that share the matrix (i.e.,
5679    those in the communicator used for matrix creation) MUST call this
5680    routine, regardless of whether any rows being zeroed are owned by
5681    them.
5682 
5683    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5684    list only rows local to itself).
5685 
5686    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5687    owns that are to be zeroed. This saves a global synchronization in the implementation.
5688 
5689    Level: intermediate
5690 
5691    Concepts: matrices^zeroing rows
5692 
5693 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5694           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5695 @*/
5696 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5697 {
5698   PetscErrorCode ierr;
5699 
5700   PetscFunctionBegin;
5701   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5702   PetscValidType(mat,1);
5703   if (numRows) PetscValidIntPointer(rows,3);
5704   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5705   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5706   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5707   MatCheckPreallocated(mat,1);
5708 
5709   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5710   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5711   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5712 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5713   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5714     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5715   }
5716 #endif
5717   PetscFunctionReturn(0);
5718 }
5719 
5720 /*@C
5721    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5722    of a set of rows of a matrix.
5723 
5724    Collective on Mat
5725 
5726    Input Parameters:
5727 +  mat - the matrix
5728 .  is - index set of rows to remove
5729 .  diag - value put in all diagonals of eliminated rows
5730 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5731 -  b - optional vector of right hand side, that will be adjusted by provided solution
5732 
5733    Notes:
5734    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5735    but does not release memory.  For the dense and block diagonal
5736    formats this does not alter the nonzero structure.
5737 
5738    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5739    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5740    merely zeroed.
5741 
5742    The user can set a value in the diagonal entry (or for the AIJ and
5743    row formats can optionally remove the main diagonal entry from the
5744    nonzero structure as well, by passing 0.0 as the final argument).
5745 
5746    For the parallel case, all processes that share the matrix (i.e.,
5747    those in the communicator used for matrix creation) MUST call this
5748    routine, regardless of whether any rows being zeroed are owned by
5749    them.
5750 
5751    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5752    list only rows local to itself).
5753 
5754    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5755    owns that are to be zeroed. This saves a global synchronization in the implementation.
5756 
5757    Level: intermediate
5758 
5759    Concepts: matrices^zeroing rows
5760 
5761 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5762           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5763 @*/
5764 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5765 {
5766   PetscInt       numRows;
5767   const PetscInt *rows;
5768   PetscErrorCode ierr;
5769 
5770   PetscFunctionBegin;
5771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5772   PetscValidType(mat,1);
5773   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5774   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5775   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5776   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5777   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5778   PetscFunctionReturn(0);
5779 }
5780 
5781 /*@C
5782    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5783    of a set of rows of a matrix. These rows must be local to the process.
5784 
5785    Collective on Mat
5786 
5787    Input Parameters:
5788 +  mat - the matrix
5789 .  numRows - the number of rows to remove
5790 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5791 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5792 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5793 -  b - optional vector of right hand side, that will be adjusted by provided solution
5794 
5795    Notes:
5796    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5797    but does not release memory.  For the dense and block diagonal
5798    formats this does not alter the nonzero structure.
5799 
5800    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5801    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5802    merely zeroed.
5803 
5804    The user can set a value in the diagonal entry (or for the AIJ and
5805    row formats can optionally remove the main diagonal entry from the
5806    nonzero structure as well, by passing 0.0 as the final argument).
5807 
5808    For the parallel case, all processes that share the matrix (i.e.,
5809    those in the communicator used for matrix creation) MUST call this
5810    routine, regardless of whether any rows being zeroed are owned by
5811    them.
5812 
5813    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5814    list only rows local to itself).
5815 
5816    The grid coordinates are across the entire grid, not just the local portion
5817 
5818    In Fortran idxm and idxn should be declared as
5819 $     MatStencil idxm(4,m)
5820    and the values inserted using
5821 $    idxm(MatStencil_i,1) = i
5822 $    idxm(MatStencil_j,1) = j
5823 $    idxm(MatStencil_k,1) = k
5824 $    idxm(MatStencil_c,1) = c
5825    etc
5826 
5827    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5828    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5829    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5830    DM_BOUNDARY_PERIODIC boundary type.
5831 
5832    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
5833    a single value per point) you can skip filling those indices.
5834 
5835    Level: intermediate
5836 
5837    Concepts: matrices^zeroing rows
5838 
5839 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5840           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5841 @*/
5842 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5843 {
5844   PetscInt       dim     = mat->stencil.dim;
5845   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5846   PetscInt       *dims   = mat->stencil.dims+1;
5847   PetscInt       *starts = mat->stencil.starts;
5848   PetscInt       *dxm    = (PetscInt*) rows;
5849   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5850   PetscErrorCode ierr;
5851 
5852   PetscFunctionBegin;
5853   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5854   PetscValidType(mat,1);
5855   if (numRows) PetscValidIntPointer(rows,3);
5856 
5857   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5858   for (i = 0; i < numRows; ++i) {
5859     /* Skip unused dimensions (they are ordered k, j, i, c) */
5860     for (j = 0; j < 3-sdim; ++j) dxm++;
5861     /* Local index in X dir */
5862     tmp = *dxm++ - starts[0];
5863     /* Loop over remaining dimensions */
5864     for (j = 0; j < dim-1; ++j) {
5865       /* If nonlocal, set index to be negative */
5866       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5867       /* Update local index */
5868       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5869     }
5870     /* Skip component slot if necessary */
5871     if (mat->stencil.noc) dxm++;
5872     /* Local row number */
5873     if (tmp >= 0) {
5874       jdxm[numNewRows++] = tmp;
5875     }
5876   }
5877   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5878   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5879   PetscFunctionReturn(0);
5880 }
5881 
5882 /*@C
5883    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5884    of a set of rows and columns of a matrix.
5885 
5886    Collective on Mat
5887 
5888    Input Parameters:
5889 +  mat - the matrix
5890 .  numRows - the number of rows/columns to remove
5891 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5892 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5893 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5894 -  b - optional vector of right hand side, that will be adjusted by provided solution
5895 
5896    Notes:
5897    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5898    but does not release memory.  For the dense and block diagonal
5899    formats this does not alter the nonzero structure.
5900 
5901    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5902    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5903    merely zeroed.
5904 
5905    The user can set a value in the diagonal entry (or for the AIJ and
5906    row formats can optionally remove the main diagonal entry from the
5907    nonzero structure as well, by passing 0.0 as the final argument).
5908 
5909    For the parallel case, all processes that share the matrix (i.e.,
5910    those in the communicator used for matrix creation) MUST call this
5911    routine, regardless of whether any rows being zeroed are owned by
5912    them.
5913 
5914    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5915    list only rows local to itself, but the row/column numbers are given in local numbering).
5916 
5917    The grid coordinates are across the entire grid, not just the local portion
5918 
5919    In Fortran idxm and idxn should be declared as
5920 $     MatStencil idxm(4,m)
5921    and the values inserted using
5922 $    idxm(MatStencil_i,1) = i
5923 $    idxm(MatStencil_j,1) = j
5924 $    idxm(MatStencil_k,1) = k
5925 $    idxm(MatStencil_c,1) = c
5926    etc
5927 
5928    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5929    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5930    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5931    DM_BOUNDARY_PERIODIC boundary type.
5932 
5933    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
5934    a single value per point) you can skip filling those indices.
5935 
5936    Level: intermediate
5937 
5938    Concepts: matrices^zeroing rows
5939 
5940 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5941           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5942 @*/
5943 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5944 {
5945   PetscInt       dim     = mat->stencil.dim;
5946   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5947   PetscInt       *dims   = mat->stencil.dims+1;
5948   PetscInt       *starts = mat->stencil.starts;
5949   PetscInt       *dxm    = (PetscInt*) rows;
5950   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5951   PetscErrorCode ierr;
5952 
5953   PetscFunctionBegin;
5954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5955   PetscValidType(mat,1);
5956   if (numRows) PetscValidIntPointer(rows,3);
5957 
5958   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5959   for (i = 0; i < numRows; ++i) {
5960     /* Skip unused dimensions (they are ordered k, j, i, c) */
5961     for (j = 0; j < 3-sdim; ++j) dxm++;
5962     /* Local index in X dir */
5963     tmp = *dxm++ - starts[0];
5964     /* Loop over remaining dimensions */
5965     for (j = 0; j < dim-1; ++j) {
5966       /* If nonlocal, set index to be negative */
5967       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5968       /* Update local index */
5969       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5970     }
5971     /* Skip component slot if necessary */
5972     if (mat->stencil.noc) dxm++;
5973     /* Local row number */
5974     if (tmp >= 0) {
5975       jdxm[numNewRows++] = tmp;
5976     }
5977   }
5978   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5979   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5980   PetscFunctionReturn(0);
5981 }
5982 
5983 /*@C
5984    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5985    of a set of rows of a matrix; using local numbering of rows.
5986 
5987    Collective on Mat
5988 
5989    Input Parameters:
5990 +  mat - the matrix
5991 .  numRows - the number of rows to remove
5992 .  rows - the global row indices
5993 .  diag - value put in all diagonals of eliminated rows
5994 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5995 -  b - optional vector of right hand side, that will be adjusted by provided solution
5996 
5997    Notes:
5998    Before calling MatZeroRowsLocal(), the user must first set the
5999    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6000 
6001    For the AIJ matrix formats this removes the old nonzero structure,
6002    but does not release memory.  For the dense and block diagonal
6003    formats this does not alter the nonzero structure.
6004 
6005    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6006    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6007    merely zeroed.
6008 
6009    The user can set a value in the diagonal entry (or for the AIJ and
6010    row formats can optionally remove the main diagonal entry from the
6011    nonzero structure as well, by passing 0.0 as the final argument).
6012 
6013    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6014    owns that are to be zeroed. This saves a global synchronization in the implementation.
6015 
6016    Level: intermediate
6017 
6018    Concepts: matrices^zeroing
6019 
6020 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6021           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6022 @*/
6023 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6024 {
6025   PetscErrorCode ierr;
6026 
6027   PetscFunctionBegin;
6028   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6029   PetscValidType(mat,1);
6030   if (numRows) PetscValidIntPointer(rows,3);
6031   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6032   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6033   MatCheckPreallocated(mat,1);
6034 
6035   if (mat->ops->zerorowslocal) {
6036     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6037   } else {
6038     IS             is, newis;
6039     const PetscInt *newRows;
6040 
6041     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6042     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6043     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6044     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6045     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6046     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6047     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6048     ierr = ISDestroy(&is);CHKERRQ(ierr);
6049   }
6050   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6051 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6052   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6053     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6054   }
6055 #endif
6056   PetscFunctionReturn(0);
6057 }
6058 
6059 /*@C
6060    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6061    of a set of rows of a matrix; using local numbering of rows.
6062 
6063    Collective on Mat
6064 
6065    Input Parameters:
6066 +  mat - the matrix
6067 .  is - index set of rows to remove
6068 .  diag - value put in all diagonals of eliminated rows
6069 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6070 -  b - optional vector of right hand side, that will be adjusted by provided solution
6071 
6072    Notes:
6073    Before calling MatZeroRowsLocalIS(), the user must first set the
6074    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6075 
6076    For the AIJ matrix formats this removes the old nonzero structure,
6077    but does not release memory.  For the dense and block diagonal
6078    formats this does not alter the nonzero structure.
6079 
6080    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6081    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6082    merely zeroed.
6083 
6084    The user can set a value in the diagonal entry (or for the AIJ and
6085    row formats can optionally remove the main diagonal entry from the
6086    nonzero structure as well, by passing 0.0 as the final argument).
6087 
6088    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6089    owns that are to be zeroed. This saves a global synchronization in the implementation.
6090 
6091    Level: intermediate
6092 
6093    Concepts: matrices^zeroing
6094 
6095 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6096           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6097 @*/
6098 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6099 {
6100   PetscErrorCode ierr;
6101   PetscInt       numRows;
6102   const PetscInt *rows;
6103 
6104   PetscFunctionBegin;
6105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6106   PetscValidType(mat,1);
6107   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6108   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6109   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6110   MatCheckPreallocated(mat,1);
6111 
6112   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6113   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6114   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6115   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6116   PetscFunctionReturn(0);
6117 }
6118 
6119 /*@C
6120    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6121    of a set of rows and columns of a matrix; using local numbering of rows.
6122 
6123    Collective on Mat
6124 
6125    Input Parameters:
6126 +  mat - the matrix
6127 .  numRows - the number of rows to remove
6128 .  rows - the global row indices
6129 .  diag - value put in all diagonals of eliminated rows
6130 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6131 -  b - optional vector of right hand side, that will be adjusted by provided solution
6132 
6133    Notes:
6134    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6135    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6136 
6137    The user can set a value in the diagonal entry (or for the AIJ and
6138    row formats can optionally remove the main diagonal entry from the
6139    nonzero structure as well, by passing 0.0 as the final argument).
6140 
6141    Level: intermediate
6142 
6143    Concepts: matrices^zeroing
6144 
6145 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6146           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6147 @*/
6148 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6149 {
6150   PetscErrorCode ierr;
6151   IS             is, newis;
6152   const PetscInt *newRows;
6153 
6154   PetscFunctionBegin;
6155   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6156   PetscValidType(mat,1);
6157   if (numRows) PetscValidIntPointer(rows,3);
6158   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6159   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6160   MatCheckPreallocated(mat,1);
6161 
6162   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6163   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6164   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6165   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6166   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6167   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6168   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6169   ierr = ISDestroy(&is);CHKERRQ(ierr);
6170   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6171 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6172   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6173     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6174   }
6175 #endif
6176   PetscFunctionReturn(0);
6177 }
6178 
6179 /*@C
6180    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6181    of a set of rows and columns of a matrix; using local numbering of rows.
6182 
6183    Collective on Mat
6184 
6185    Input Parameters:
6186 +  mat - the matrix
6187 .  is - index set of rows to remove
6188 .  diag - value put in all diagonals of eliminated rows
6189 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6190 -  b - optional vector of right hand side, that will be adjusted by provided solution
6191 
6192    Notes:
6193    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6194    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6195 
6196    The user can set a value in the diagonal entry (or for the AIJ and
6197    row formats can optionally remove the main diagonal entry from the
6198    nonzero structure as well, by passing 0.0 as the final argument).
6199 
6200    Level: intermediate
6201 
6202    Concepts: matrices^zeroing
6203 
6204 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6205           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6206 @*/
6207 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6208 {
6209   PetscErrorCode ierr;
6210   PetscInt       numRows;
6211   const PetscInt *rows;
6212 
6213   PetscFunctionBegin;
6214   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6215   PetscValidType(mat,1);
6216   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6217   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6218   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6219   MatCheckPreallocated(mat,1);
6220 
6221   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6222   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6223   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6224   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6225   PetscFunctionReturn(0);
6226 }
6227 
6228 /*@C
6229    MatGetSize - Returns the numbers of rows and columns in a matrix.
6230 
6231    Not Collective
6232 
6233    Input Parameter:
6234 .  mat - the matrix
6235 
6236    Output Parameters:
6237 +  m - the number of global rows
6238 -  n - the number of global columns
6239 
6240    Note: both output parameters can be NULL on input.
6241 
6242    Level: beginner
6243 
6244    Concepts: matrices^size
6245 
6246 .seealso: MatGetLocalSize()
6247 @*/
6248 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6249 {
6250   PetscFunctionBegin;
6251   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6252   if (m) *m = mat->rmap->N;
6253   if (n) *n = mat->cmap->N;
6254   PetscFunctionReturn(0);
6255 }
6256 
6257 /*@C
6258    MatGetLocalSize - Returns the number of rows and columns in a matrix
6259    stored locally.  This information may be implementation dependent, so
6260    use with care.
6261 
6262    Not Collective
6263 
6264    Input Parameters:
6265 .  mat - the matrix
6266 
6267    Output Parameters:
6268 +  m - the number of local rows
6269 -  n - the number of local columns
6270 
6271    Note: both output parameters can be NULL on input.
6272 
6273    Level: beginner
6274 
6275    Concepts: matrices^local size
6276 
6277 .seealso: MatGetSize()
6278 @*/
6279 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6280 {
6281   PetscFunctionBegin;
6282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6283   if (m) PetscValidIntPointer(m,2);
6284   if (n) PetscValidIntPointer(n,3);
6285   if (m) *m = mat->rmap->n;
6286   if (n) *n = mat->cmap->n;
6287   PetscFunctionReturn(0);
6288 }
6289 
6290 /*@C
6291    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6292    this processor. (The columns of the "diagonal block")
6293 
6294    Not Collective, unless matrix has not been allocated, then collective on Mat
6295 
6296    Input Parameters:
6297 .  mat - the matrix
6298 
6299    Output Parameters:
6300 +  m - the global index of the first local column
6301 -  n - one more than the global index of the last local column
6302 
6303    Notes: both output parameters can be NULL on input.
6304 
6305    Level: developer
6306 
6307    Concepts: matrices^column ownership
6308 
6309 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6310 
6311 @*/
6312 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6313 {
6314   PetscFunctionBegin;
6315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6316   PetscValidType(mat,1);
6317   if (m) PetscValidIntPointer(m,2);
6318   if (n) PetscValidIntPointer(n,3);
6319   MatCheckPreallocated(mat,1);
6320   if (m) *m = mat->cmap->rstart;
6321   if (n) *n = mat->cmap->rend;
6322   PetscFunctionReturn(0);
6323 }
6324 
6325 /*@C
6326    MatGetOwnershipRange - Returns the range of matrix rows owned by
6327    this processor, assuming that the matrix is laid out with the first
6328    n1 rows on the first processor, the next n2 rows on the second, etc.
6329    For certain parallel layouts this range may not be well defined.
6330 
6331    Not Collective
6332 
6333    Input Parameters:
6334 .  mat - the matrix
6335 
6336    Output Parameters:
6337 +  m - the global index of the first local row
6338 -  n - one more than the global index of the last local row
6339 
6340    Note: Both output parameters can be NULL on input.
6341 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6342 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6343 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6344 
6345    Level: beginner
6346 
6347    Concepts: matrices^row ownership
6348 
6349 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6350 
6351 @*/
6352 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6353 {
6354   PetscFunctionBegin;
6355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6356   PetscValidType(mat,1);
6357   if (m) PetscValidIntPointer(m,2);
6358   if (n) PetscValidIntPointer(n,3);
6359   MatCheckPreallocated(mat,1);
6360   if (m) *m = mat->rmap->rstart;
6361   if (n) *n = mat->rmap->rend;
6362   PetscFunctionReturn(0);
6363 }
6364 
6365 /*@C
6366    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6367    each process
6368 
6369    Not Collective, unless matrix has not been allocated, then collective on Mat
6370 
6371    Input Parameters:
6372 .  mat - the matrix
6373 
6374    Output Parameters:
6375 .  ranges - start of each processors portion plus one more than the total length at the end
6376 
6377    Level: beginner
6378 
6379    Concepts: matrices^row ownership
6380 
6381 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6382 
6383 @*/
6384 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6385 {
6386   PetscErrorCode ierr;
6387 
6388   PetscFunctionBegin;
6389   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6390   PetscValidType(mat,1);
6391   MatCheckPreallocated(mat,1);
6392   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6393   PetscFunctionReturn(0);
6394 }
6395 
6396 /*@C
6397    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6398    this processor. (The columns of the "diagonal blocks" for each process)
6399 
6400    Not Collective, unless matrix has not been allocated, then collective on Mat
6401 
6402    Input Parameters:
6403 .  mat - the matrix
6404 
6405    Output Parameters:
6406 .  ranges - start of each processors portion plus one more then the total length at the end
6407 
6408    Level: beginner
6409 
6410    Concepts: matrices^column ownership
6411 
6412 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6413 
6414 @*/
6415 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6416 {
6417   PetscErrorCode ierr;
6418 
6419   PetscFunctionBegin;
6420   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6421   PetscValidType(mat,1);
6422   MatCheckPreallocated(mat,1);
6423   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6424   PetscFunctionReturn(0);
6425 }
6426 
6427 /*@C
6428    MatGetOwnershipIS - Get row and column ownership as index sets
6429 
6430    Not Collective
6431 
6432    Input Arguments:
6433 .  A - matrix of type Elemental
6434 
6435    Output Arguments:
6436 +  rows - rows in which this process owns elements
6437 .  cols - columns in which this process owns elements
6438 
6439    Level: intermediate
6440 
6441 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6442 @*/
6443 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6444 {
6445   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6446 
6447   PetscFunctionBegin;
6448   MatCheckPreallocated(A,1);
6449   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6450   if (f) {
6451     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6452   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6453     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6454     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6455   }
6456   PetscFunctionReturn(0);
6457 }
6458 
6459 /*@C
6460    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6461    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6462    to complete the factorization.
6463 
6464    Collective on Mat
6465 
6466    Input Parameters:
6467 +  mat - the matrix
6468 .  row - row permutation
6469 .  column - column permutation
6470 -  info - structure containing
6471 $      levels - number of levels of fill.
6472 $      expected fill - as ratio of original fill.
6473 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6474                 missing diagonal entries)
6475 
6476    Output Parameters:
6477 .  fact - new matrix that has been symbolically factored
6478 
6479    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6480 
6481    Most users should employ the simplified KSP interface for linear solvers
6482    instead of working directly with matrix algebra routines such as this.
6483    See, e.g., KSPCreate().
6484 
6485    Level: developer
6486 
6487   Concepts: matrices^symbolic LU factorization
6488   Concepts: matrices^factorization
6489   Concepts: LU^symbolic factorization
6490 
6491 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6492           MatGetOrdering(), MatFactorInfo
6493 
6494     Developer Note: fortran interface is not autogenerated as the f90
6495     interface defintion cannot be generated correctly [due to MatFactorInfo]
6496 
6497 @*/
6498 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6499 {
6500   PetscErrorCode ierr;
6501 
6502   PetscFunctionBegin;
6503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6504   PetscValidType(mat,1);
6505   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6506   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6507   PetscValidPointer(info,4);
6508   PetscValidPointer(fact,5);
6509   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6510   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6511   if (!(fact)->ops->ilufactorsymbolic) {
6512     MatSolverType spackage;
6513     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6514     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6515   }
6516   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6517   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6518   MatCheckPreallocated(mat,2);
6519 
6520   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6521   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6522   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6523   PetscFunctionReturn(0);
6524 }
6525 
6526 /*@C
6527    MatICCFactorSymbolic - Performs symbolic incomplete
6528    Cholesky factorization for a symmetric matrix.  Use
6529    MatCholeskyFactorNumeric() to complete the factorization.
6530 
6531    Collective on Mat
6532 
6533    Input Parameters:
6534 +  mat - the matrix
6535 .  perm - row and column permutation
6536 -  info - structure containing
6537 $      levels - number of levels of fill.
6538 $      expected fill - as ratio of original fill.
6539 
6540    Output Parameter:
6541 .  fact - the factored matrix
6542 
6543    Notes:
6544    Most users should employ the KSP interface for linear solvers
6545    instead of working directly with matrix algebra routines such as this.
6546    See, e.g., KSPCreate().
6547 
6548    Level: developer
6549 
6550   Concepts: matrices^symbolic incomplete Cholesky factorization
6551   Concepts: matrices^factorization
6552   Concepts: Cholsky^symbolic factorization
6553 
6554 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6555 
6556     Developer Note: fortran interface is not autogenerated as the f90
6557     interface defintion cannot be generated correctly [due to MatFactorInfo]
6558 
6559 @*/
6560 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6561 {
6562   PetscErrorCode ierr;
6563 
6564   PetscFunctionBegin;
6565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6566   PetscValidType(mat,1);
6567   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6568   PetscValidPointer(info,3);
6569   PetscValidPointer(fact,4);
6570   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6571   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6572   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6573   if (!(fact)->ops->iccfactorsymbolic) {
6574     MatSolverType spackage;
6575     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6576     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6577   }
6578   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6579   MatCheckPreallocated(mat,2);
6580 
6581   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6582   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6583   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6584   PetscFunctionReturn(0);
6585 }
6586 
6587 /*@C
6588    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6589    points to an array of valid matrices, they may be reused to store the new
6590    submatrices.
6591 
6592    Collective on Mat
6593 
6594    Input Parameters:
6595 +  mat - the matrix
6596 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6597 .  irow, icol - index sets of rows and columns to extract
6598 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6599 
6600    Output Parameter:
6601 .  submat - the array of submatrices
6602 
6603    Notes:
6604    MatCreateSubMatrices() can extract ONLY sequential submatrices
6605    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6606    to extract a parallel submatrix.
6607 
6608    Some matrix types place restrictions on the row and column
6609    indices, such as that they be sorted or that they be equal to each other.
6610 
6611    The index sets may not have duplicate entries.
6612 
6613    When extracting submatrices from a parallel matrix, each processor can
6614    form a different submatrix by setting the rows and columns of its
6615    individual index sets according to the local submatrix desired.
6616 
6617    When finished using the submatrices, the user should destroy
6618    them with MatDestroySubMatrices().
6619 
6620    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6621    original matrix has not changed from that last call to MatCreateSubMatrices().
6622 
6623    This routine creates the matrices in submat; you should NOT create them before
6624    calling it. It also allocates the array of matrix pointers submat.
6625 
6626    For BAIJ matrices the index sets must respect the block structure, that is if they
6627    request one row/column in a block, they must request all rows/columns that are in
6628    that block. For example, if the block size is 2 you cannot request just row 0 and
6629    column 0.
6630 
6631    Fortran Note:
6632    The Fortran interface is slightly different from that given below; it
6633    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6634 
6635    Level: advanced
6636 
6637    Concepts: matrices^accessing submatrices
6638    Concepts: submatrices
6639 
6640 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6641 @*/
6642 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6643 {
6644   PetscErrorCode ierr;
6645   PetscInt       i;
6646   PetscBool      eq;
6647 
6648   PetscFunctionBegin;
6649   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6650   PetscValidType(mat,1);
6651   if (n) {
6652     PetscValidPointer(irow,3);
6653     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6654     PetscValidPointer(icol,4);
6655     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6656   }
6657   PetscValidPointer(submat,6);
6658   if (n && scall == MAT_REUSE_MATRIX) {
6659     PetscValidPointer(*submat,6);
6660     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6661   }
6662   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6663   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6664   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6665   MatCheckPreallocated(mat,1);
6666 
6667   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6668   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6669   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6670   for (i=0; i<n; i++) {
6671     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6672     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6673       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6674       if (eq) {
6675         if (mat->symmetric) {
6676           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6677         } else if (mat->hermitian) {
6678           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6679         } else if (mat->structurally_symmetric) {
6680           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6681         }
6682       }
6683     }
6684   }
6685   PetscFunctionReturn(0);
6686 }
6687 
6688 /*@C
6689    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6690 
6691    Collective on Mat
6692 
6693    Input Parameters:
6694 +  mat - the matrix
6695 .  n   - the number of submatrixes to be extracted
6696 .  irow, icol - index sets of rows and columns to extract
6697 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6698 
6699    Output Parameter:
6700 .  submat - the array of submatrices
6701 
6702    Level: advanced
6703 
6704    Concepts: matrices^accessing submatrices
6705    Concepts: submatrices
6706 
6707 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6708 @*/
6709 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6710 {
6711   PetscErrorCode ierr;
6712   PetscInt       i;
6713   PetscBool      eq;
6714 
6715   PetscFunctionBegin;
6716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6717   PetscValidType(mat,1);
6718   if (n) {
6719     PetscValidPointer(irow,3);
6720     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6721     PetscValidPointer(icol,4);
6722     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6723   }
6724   PetscValidPointer(submat,6);
6725   if (n && scall == MAT_REUSE_MATRIX) {
6726     PetscValidPointer(*submat,6);
6727     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6728   }
6729   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6730   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6731   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6732   MatCheckPreallocated(mat,1);
6733 
6734   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6735   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6736   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6737   for (i=0; i<n; i++) {
6738     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6739       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6740       if (eq) {
6741         if (mat->symmetric) {
6742           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6743         } else if (mat->hermitian) {
6744           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6745         } else if (mat->structurally_symmetric) {
6746           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6747         }
6748       }
6749     }
6750   }
6751   PetscFunctionReturn(0);
6752 }
6753 
6754 /*@C
6755    MatDestroyMatrices - Destroys an array of matrices.
6756 
6757    Collective on Mat
6758 
6759    Input Parameters:
6760 +  n - the number of local matrices
6761 -  mat - the matrices (note that this is a pointer to the array of matrices)
6762 
6763    Level: advanced
6764 
6765     Notes: Frees not only the matrices, but also the array that contains the matrices
6766            In Fortran will not free the array.
6767 
6768 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6769 @*/
6770 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6771 {
6772   PetscErrorCode ierr;
6773   PetscInt       i;
6774 
6775   PetscFunctionBegin;
6776   if (!*mat) PetscFunctionReturn(0);
6777   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6778   PetscValidPointer(mat,2);
6779 
6780   for (i=0; i<n; i++) {
6781     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6782   }
6783 
6784   /* memory is allocated even if n = 0 */
6785   ierr = PetscFree(*mat);CHKERRQ(ierr);
6786   PetscFunctionReturn(0);
6787 }
6788 
6789 /*@C
6790    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6791 
6792    Collective on Mat
6793 
6794    Input Parameters:
6795 +  n - the number of local matrices
6796 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6797                        sequence of MatCreateSubMatrices())
6798 
6799    Level: advanced
6800 
6801     Notes: Frees not only the matrices, but also the array that contains the matrices
6802            In Fortran will not free the array.
6803 
6804 .seealso: MatCreateSubMatrices()
6805 @*/
6806 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6807 {
6808   PetscErrorCode ierr;
6809   Mat            mat0;
6810 
6811   PetscFunctionBegin;
6812   if (!*mat) PetscFunctionReturn(0);
6813   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6814   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6815   PetscValidPointer(mat,2);
6816 
6817   mat0 = (*mat)[0];
6818   if (mat0 && mat0->ops->destroysubmatrices) {
6819     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6820   } else {
6821     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6822   }
6823   PetscFunctionReturn(0);
6824 }
6825 
6826 /*@C
6827    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6828 
6829    Collective on Mat
6830 
6831    Input Parameters:
6832 .  mat - the matrix
6833 
6834    Output Parameter:
6835 .  matstruct - the sequential matrix with the nonzero structure of mat
6836 
6837   Level: intermediate
6838 
6839 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6840 @*/
6841 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6842 {
6843   PetscErrorCode ierr;
6844 
6845   PetscFunctionBegin;
6846   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6847   PetscValidPointer(matstruct,2);
6848 
6849   PetscValidType(mat,1);
6850   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6851   MatCheckPreallocated(mat,1);
6852 
6853   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6854   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6855   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6856   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6857   PetscFunctionReturn(0);
6858 }
6859 
6860 /*@C
6861    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6862 
6863    Collective on Mat
6864 
6865    Input Parameters:
6866 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6867                        sequence of MatGetSequentialNonzeroStructure())
6868 
6869    Level: advanced
6870 
6871     Notes: Frees not only the matrices, but also the array that contains the matrices
6872 
6873 .seealso: MatGetSeqNonzeroStructure()
6874 @*/
6875 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6876 {
6877   PetscErrorCode ierr;
6878 
6879   PetscFunctionBegin;
6880   PetscValidPointer(mat,1);
6881   ierr = MatDestroy(mat);CHKERRQ(ierr);
6882   PetscFunctionReturn(0);
6883 }
6884 
6885 /*@
6886    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6887    replaces the index sets by larger ones that represent submatrices with
6888    additional overlap.
6889 
6890    Collective on Mat
6891 
6892    Input Parameters:
6893 +  mat - the matrix
6894 .  n   - the number of index sets
6895 .  is  - the array of index sets (these index sets will changed during the call)
6896 -  ov  - the additional overlap requested
6897 
6898    Options Database:
6899 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6900 
6901    Level: developer
6902 
6903    Concepts: overlap
6904    Concepts: ASM^computing overlap
6905 
6906 .seealso: MatCreateSubMatrices()
6907 @*/
6908 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6909 {
6910   PetscErrorCode ierr;
6911 
6912   PetscFunctionBegin;
6913   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6914   PetscValidType(mat,1);
6915   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6916   if (n) {
6917     PetscValidPointer(is,3);
6918     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6919   }
6920   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6921   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6922   MatCheckPreallocated(mat,1);
6923 
6924   if (!ov) PetscFunctionReturn(0);
6925   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6926   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6927   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6928   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6929   PetscFunctionReturn(0);
6930 }
6931 
6932 
6933 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6934 
6935 /*@
6936    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6937    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6938    additional overlap.
6939 
6940    Collective on Mat
6941 
6942    Input Parameters:
6943 +  mat - the matrix
6944 .  n   - the number of index sets
6945 .  is  - the array of index sets (these index sets will changed during the call)
6946 -  ov  - the additional overlap requested
6947 
6948    Options Database:
6949 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6950 
6951    Level: developer
6952 
6953    Concepts: overlap
6954    Concepts: ASM^computing overlap
6955 
6956 .seealso: MatCreateSubMatrices()
6957 @*/
6958 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6959 {
6960   PetscInt       i;
6961   PetscErrorCode ierr;
6962 
6963   PetscFunctionBegin;
6964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6965   PetscValidType(mat,1);
6966   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6967   if (n) {
6968     PetscValidPointer(is,3);
6969     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6970   }
6971   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6972   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6973   MatCheckPreallocated(mat,1);
6974   if (!ov) PetscFunctionReturn(0);
6975   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6976   for(i=0; i<n; i++){
6977 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
6978   }
6979   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6980   PetscFunctionReturn(0);
6981 }
6982 
6983 
6984 
6985 
6986 /*@
6987    MatGetBlockSize - Returns the matrix block size.
6988 
6989    Not Collective
6990 
6991    Input Parameter:
6992 .  mat - the matrix
6993 
6994    Output Parameter:
6995 .  bs - block size
6996 
6997    Notes:
6998     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6999 
7000    If the block size has not been set yet this routine returns 1.
7001 
7002    Level: intermediate
7003 
7004    Concepts: matrices^block size
7005 
7006 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7007 @*/
7008 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7009 {
7010   PetscFunctionBegin;
7011   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7012   PetscValidIntPointer(bs,2);
7013   *bs = PetscAbs(mat->rmap->bs);
7014   PetscFunctionReturn(0);
7015 }
7016 
7017 /*@
7018    MatGetBlockSizes - Returns the matrix block row and column sizes.
7019 
7020    Not Collective
7021 
7022    Input Parameter:
7023 .  mat - the matrix
7024 
7025    Output Parameter:
7026 .  rbs - row block size
7027 .  cbs - column block size
7028 
7029    Notes:
7030     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7031     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7032 
7033    If a block size has not been set yet this routine returns 1.
7034 
7035    Level: intermediate
7036 
7037    Concepts: matrices^block size
7038 
7039 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7040 @*/
7041 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7042 {
7043   PetscFunctionBegin;
7044   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7045   if (rbs) PetscValidIntPointer(rbs,2);
7046   if (cbs) PetscValidIntPointer(cbs,3);
7047   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7048   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 /*@
7053    MatSetBlockSize - Sets the matrix block size.
7054 
7055    Logically Collective on Mat
7056 
7057    Input Parameters:
7058 +  mat - the matrix
7059 -  bs - block size
7060 
7061    Notes:
7062     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7063     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7064 
7065     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7066     is compatible with the matrix local sizes.
7067 
7068    Level: intermediate
7069 
7070    Concepts: matrices^block size
7071 
7072 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7073 @*/
7074 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7075 {
7076   PetscErrorCode ierr;
7077 
7078   PetscFunctionBegin;
7079   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7080   PetscValidLogicalCollectiveInt(mat,bs,2);
7081   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7082   PetscFunctionReturn(0);
7083 }
7084 
7085 /*@
7086    MatSetBlockSizes - Sets the matrix block row and column sizes.
7087 
7088    Logically Collective on Mat
7089 
7090    Input Parameters:
7091 +  mat - the matrix
7092 -  rbs - row block size
7093 -  cbs - column block size
7094 
7095    Notes:
7096     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7097     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7098     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7099 
7100     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7101     are compatible with the matrix local sizes.
7102 
7103     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7104 
7105    Level: intermediate
7106 
7107    Concepts: matrices^block size
7108 
7109 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7110 @*/
7111 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7112 {
7113   PetscErrorCode ierr;
7114 
7115   PetscFunctionBegin;
7116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7117   PetscValidLogicalCollectiveInt(mat,rbs,2);
7118   PetscValidLogicalCollectiveInt(mat,cbs,3);
7119   if (mat->ops->setblocksizes) {
7120     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7121   }
7122   if (mat->rmap->refcnt) {
7123     ISLocalToGlobalMapping l2g = NULL;
7124     PetscLayout            nmap = NULL;
7125 
7126     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7127     if (mat->rmap->mapping) {
7128       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7129     }
7130     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7131     mat->rmap = nmap;
7132     mat->rmap->mapping = l2g;
7133   }
7134   if (mat->cmap->refcnt) {
7135     ISLocalToGlobalMapping l2g = NULL;
7136     PetscLayout            nmap = NULL;
7137 
7138     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7139     if (mat->cmap->mapping) {
7140       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7141     }
7142     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7143     mat->cmap = nmap;
7144     mat->cmap->mapping = l2g;
7145   }
7146   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7147   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7148   PetscFunctionReturn(0);
7149 }
7150 
7151 /*@
7152    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7153 
7154    Logically Collective on Mat
7155 
7156    Input Parameters:
7157 +  mat - the matrix
7158 .  fromRow - matrix from which to copy row block size
7159 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7160 
7161    Level: developer
7162 
7163    Concepts: matrices^block size
7164 
7165 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7166 @*/
7167 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7168 {
7169   PetscErrorCode ierr;
7170 
7171   PetscFunctionBegin;
7172   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7173   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7174   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7175   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7176   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7177   PetscFunctionReturn(0);
7178 }
7179 
7180 /*@
7181    MatResidual - Default routine to calculate the residual.
7182 
7183    Collective on Mat and Vec
7184 
7185    Input Parameters:
7186 +  mat - the matrix
7187 .  b   - the right-hand-side
7188 -  x   - the approximate solution
7189 
7190    Output Parameter:
7191 .  r - location to store the residual
7192 
7193    Level: developer
7194 
7195 .keywords: MG, default, multigrid, residual
7196 
7197 .seealso: PCMGSetResidual()
7198 @*/
7199 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7200 {
7201   PetscErrorCode ierr;
7202 
7203   PetscFunctionBegin;
7204   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7205   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7206   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7207   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7208   PetscValidType(mat,1);
7209   MatCheckPreallocated(mat,1);
7210   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7211   if (!mat->ops->residual) {
7212     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7213     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7214   } else {
7215     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7216   }
7217   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7218   PetscFunctionReturn(0);
7219 }
7220 
7221 /*@C
7222     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7223 
7224    Collective on Mat
7225 
7226     Input Parameters:
7227 +   mat - the matrix
7228 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7229 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7230 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7231                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7232                  always used.
7233 
7234     Output Parameters:
7235 +   n - number of rows in the (possibly compressed) matrix
7236 .   ia - the row pointers [of length n+1]
7237 .   ja - the column indices
7238 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7239            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7240 
7241     Level: developer
7242 
7243     Notes:
7244     You CANNOT change any of the ia[] or ja[] values.
7245 
7246     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7247 
7248     Fortran Notes:
7249     In Fortran use
7250 $
7251 $      PetscInt ia(1), ja(1)
7252 $      PetscOffset iia, jja
7253 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7254 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7255 
7256      or
7257 $
7258 $    PetscInt, pointer :: ia(:),ja(:)
7259 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7260 $    ! Access the ith and jth entries via ia(i) and ja(j)
7261 
7262 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7263 @*/
7264 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7265 {
7266   PetscErrorCode ierr;
7267 
7268   PetscFunctionBegin;
7269   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7270   PetscValidType(mat,1);
7271   PetscValidIntPointer(n,5);
7272   if (ia) PetscValidIntPointer(ia,6);
7273   if (ja) PetscValidIntPointer(ja,7);
7274   PetscValidIntPointer(done,8);
7275   MatCheckPreallocated(mat,1);
7276   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7277   else {
7278     *done = PETSC_TRUE;
7279     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7280     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7281     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7282   }
7283   PetscFunctionReturn(0);
7284 }
7285 
7286 /*@C
7287     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7288 
7289     Collective on Mat
7290 
7291     Input Parameters:
7292 +   mat - the matrix
7293 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7294 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7295                 symmetrized
7296 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7297                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7298                  always used.
7299 .   n - number of columns in the (possibly compressed) matrix
7300 .   ia - the column pointers
7301 -   ja - the row indices
7302 
7303     Output Parameters:
7304 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7305 
7306     Note:
7307     This routine zeros out n, ia, and ja. This is to prevent accidental
7308     us of the array after it has been restored. If you pass NULL, it will
7309     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7310 
7311     Level: developer
7312 
7313 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7314 @*/
7315 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7316 {
7317   PetscErrorCode ierr;
7318 
7319   PetscFunctionBegin;
7320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7321   PetscValidType(mat,1);
7322   PetscValidIntPointer(n,4);
7323   if (ia) PetscValidIntPointer(ia,5);
7324   if (ja) PetscValidIntPointer(ja,6);
7325   PetscValidIntPointer(done,7);
7326   MatCheckPreallocated(mat,1);
7327   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7328   else {
7329     *done = PETSC_TRUE;
7330     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7331   }
7332   PetscFunctionReturn(0);
7333 }
7334 
7335 /*@C
7336     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7337     MatGetRowIJ().
7338 
7339     Collective on Mat
7340 
7341     Input Parameters:
7342 +   mat - the matrix
7343 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7344 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7345                 symmetrized
7346 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7347                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7348                  always used.
7349 .   n - size of (possibly compressed) matrix
7350 .   ia - the row pointers
7351 -   ja - the column indices
7352 
7353     Output Parameters:
7354 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7355 
7356     Note:
7357     This routine zeros out n, ia, and ja. This is to prevent accidental
7358     us of the array after it has been restored. If you pass NULL, it will
7359     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7360 
7361     Level: developer
7362 
7363 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7364 @*/
7365 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7366 {
7367   PetscErrorCode ierr;
7368 
7369   PetscFunctionBegin;
7370   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7371   PetscValidType(mat,1);
7372   if (ia) PetscValidIntPointer(ia,6);
7373   if (ja) PetscValidIntPointer(ja,7);
7374   PetscValidIntPointer(done,8);
7375   MatCheckPreallocated(mat,1);
7376 
7377   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7378   else {
7379     *done = PETSC_TRUE;
7380     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7381     if (n)  *n = 0;
7382     if (ia) *ia = NULL;
7383     if (ja) *ja = NULL;
7384   }
7385   PetscFunctionReturn(0);
7386 }
7387 
7388 /*@C
7389     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7390     MatGetColumnIJ().
7391 
7392     Collective on Mat
7393 
7394     Input Parameters:
7395 +   mat - the matrix
7396 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7397 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7398                 symmetrized
7399 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7400                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7401                  always used.
7402 
7403     Output Parameters:
7404 +   n - size of (possibly compressed) matrix
7405 .   ia - the column pointers
7406 .   ja - the row indices
7407 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7408 
7409     Level: developer
7410 
7411 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7412 @*/
7413 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7414 {
7415   PetscErrorCode ierr;
7416 
7417   PetscFunctionBegin;
7418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7419   PetscValidType(mat,1);
7420   if (ia) PetscValidIntPointer(ia,5);
7421   if (ja) PetscValidIntPointer(ja,6);
7422   PetscValidIntPointer(done,7);
7423   MatCheckPreallocated(mat,1);
7424 
7425   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7426   else {
7427     *done = PETSC_TRUE;
7428     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7429     if (n)  *n = 0;
7430     if (ia) *ia = NULL;
7431     if (ja) *ja = NULL;
7432   }
7433   PetscFunctionReturn(0);
7434 }
7435 
7436 /*@C
7437     MatColoringPatch -Used inside matrix coloring routines that
7438     use MatGetRowIJ() and/or MatGetColumnIJ().
7439 
7440     Collective on Mat
7441 
7442     Input Parameters:
7443 +   mat - the matrix
7444 .   ncolors - max color value
7445 .   n   - number of entries in colorarray
7446 -   colorarray - array indicating color for each column
7447 
7448     Output Parameters:
7449 .   iscoloring - coloring generated using colorarray information
7450 
7451     Level: developer
7452 
7453 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7454 
7455 @*/
7456 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7457 {
7458   PetscErrorCode ierr;
7459 
7460   PetscFunctionBegin;
7461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7462   PetscValidType(mat,1);
7463   PetscValidIntPointer(colorarray,4);
7464   PetscValidPointer(iscoloring,5);
7465   MatCheckPreallocated(mat,1);
7466 
7467   if (!mat->ops->coloringpatch) {
7468     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7469   } else {
7470     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7471   }
7472   PetscFunctionReturn(0);
7473 }
7474 
7475 
7476 /*@
7477    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7478 
7479    Logically Collective on Mat
7480 
7481    Input Parameter:
7482 .  mat - the factored matrix to be reset
7483 
7484    Notes:
7485    This routine should be used only with factored matrices formed by in-place
7486    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7487    format).  This option can save memory, for example, when solving nonlinear
7488    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7489    ILU(0) preconditioner.
7490 
7491    Note that one can specify in-place ILU(0) factorization by calling
7492 .vb
7493      PCType(pc,PCILU);
7494      PCFactorSeUseInPlace(pc);
7495 .ve
7496    or by using the options -pc_type ilu -pc_factor_in_place
7497 
7498    In-place factorization ILU(0) can also be used as a local
7499    solver for the blocks within the block Jacobi or additive Schwarz
7500    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7501    for details on setting local solver options.
7502 
7503    Most users should employ the simplified KSP interface for linear solvers
7504    instead of working directly with matrix algebra routines such as this.
7505    See, e.g., KSPCreate().
7506 
7507    Level: developer
7508 
7509 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7510 
7511    Concepts: matrices^unfactored
7512 
7513 @*/
7514 PetscErrorCode MatSetUnfactored(Mat mat)
7515 {
7516   PetscErrorCode ierr;
7517 
7518   PetscFunctionBegin;
7519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7520   PetscValidType(mat,1);
7521   MatCheckPreallocated(mat,1);
7522   mat->factortype = MAT_FACTOR_NONE;
7523   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7524   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7525   PetscFunctionReturn(0);
7526 }
7527 
7528 /*MC
7529     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7530 
7531     Synopsis:
7532     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7533 
7534     Not collective
7535 
7536     Input Parameter:
7537 .   x - matrix
7538 
7539     Output Parameters:
7540 +   xx_v - the Fortran90 pointer to the array
7541 -   ierr - error code
7542 
7543     Example of Usage:
7544 .vb
7545       PetscScalar, pointer xx_v(:,:)
7546       ....
7547       call MatDenseGetArrayF90(x,xx_v,ierr)
7548       a = xx_v(3)
7549       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7550 .ve
7551 
7552     Level: advanced
7553 
7554 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7555 
7556     Concepts: matrices^accessing array
7557 
7558 M*/
7559 
7560 /*MC
7561     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7562     accessed with MatDenseGetArrayF90().
7563 
7564     Synopsis:
7565     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7566 
7567     Not collective
7568 
7569     Input Parameters:
7570 +   x - matrix
7571 -   xx_v - the Fortran90 pointer to the array
7572 
7573     Output Parameter:
7574 .   ierr - error code
7575 
7576     Example of Usage:
7577 .vb
7578        PetscScalar, pointer xx_v(:,:)
7579        ....
7580        call MatDenseGetArrayF90(x,xx_v,ierr)
7581        a = xx_v(3)
7582        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7583 .ve
7584 
7585     Level: advanced
7586 
7587 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7588 
7589 M*/
7590 
7591 
7592 /*MC
7593     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7594 
7595     Synopsis:
7596     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7597 
7598     Not collective
7599 
7600     Input Parameter:
7601 .   x - matrix
7602 
7603     Output Parameters:
7604 +   xx_v - the Fortran90 pointer to the array
7605 -   ierr - error code
7606 
7607     Example of Usage:
7608 .vb
7609       PetscScalar, pointer xx_v(:)
7610       ....
7611       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7612       a = xx_v(3)
7613       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7614 .ve
7615 
7616     Level: advanced
7617 
7618 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7619 
7620     Concepts: matrices^accessing array
7621 
7622 M*/
7623 
7624 /*MC
7625     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7626     accessed with MatSeqAIJGetArrayF90().
7627 
7628     Synopsis:
7629     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7630 
7631     Not collective
7632 
7633     Input Parameters:
7634 +   x - matrix
7635 -   xx_v - the Fortran90 pointer to the array
7636 
7637     Output Parameter:
7638 .   ierr - error code
7639 
7640     Example of Usage:
7641 .vb
7642        PetscScalar, pointer xx_v(:)
7643        ....
7644        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7645        a = xx_v(3)
7646        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7647 .ve
7648 
7649     Level: advanced
7650 
7651 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7652 
7653 M*/
7654 
7655 
7656 /*@
7657     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7658                       as the original matrix.
7659 
7660     Collective on Mat
7661 
7662     Input Parameters:
7663 +   mat - the original matrix
7664 .   isrow - parallel IS containing the rows this processor should obtain
7665 .   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.
7666 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7667 
7668     Output Parameter:
7669 .   newmat - the new submatrix, of the same type as the old
7670 
7671     Level: advanced
7672 
7673     Notes:
7674     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7675 
7676     Some matrix types place restrictions on the row and column indices, such
7677     as that they be sorted or that they be equal to each other.
7678 
7679     The index sets may not have duplicate entries.
7680 
7681       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7682    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7683    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7684    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7685    you are finished using it.
7686 
7687     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7688     the input matrix.
7689 
7690     If iscol is NULL then all columns are obtained (not supported in Fortran).
7691 
7692    Example usage:
7693    Consider the following 8x8 matrix with 34 non-zero values, that is
7694    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7695    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7696    as follows:
7697 
7698 .vb
7699             1  2  0  |  0  3  0  |  0  4
7700     Proc0   0  5  6  |  7  0  0  |  8  0
7701             9  0 10  | 11  0  0  | 12  0
7702     -------------------------------------
7703            13  0 14  | 15 16 17  |  0  0
7704     Proc1   0 18  0  | 19 20 21  |  0  0
7705             0  0  0  | 22 23  0  | 24  0
7706     -------------------------------------
7707     Proc2  25 26 27  |  0  0 28  | 29  0
7708            30  0  0  | 31 32 33  |  0 34
7709 .ve
7710 
7711     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7712 
7713 .vb
7714             2  0  |  0  3  0  |  0
7715     Proc0   5  6  |  7  0  0  |  8
7716     -------------------------------
7717     Proc1  18  0  | 19 20 21  |  0
7718     -------------------------------
7719     Proc2  26 27  |  0  0 28  | 29
7720             0  0  | 31 32 33  |  0
7721 .ve
7722 
7723 
7724     Concepts: matrices^submatrices
7725 
7726 .seealso: MatCreateSubMatrices()
7727 @*/
7728 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7729 {
7730   PetscErrorCode ierr;
7731   PetscMPIInt    size;
7732   Mat            *local;
7733   IS             iscoltmp;
7734 
7735   PetscFunctionBegin;
7736   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7737   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7738   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7739   PetscValidPointer(newmat,5);
7740   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7741   PetscValidType(mat,1);
7742   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7743   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7744 
7745   MatCheckPreallocated(mat,1);
7746   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7747 
7748   if (!iscol || isrow == iscol) {
7749     PetscBool   stride;
7750     PetscMPIInt grabentirematrix = 0,grab;
7751     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7752     if (stride) {
7753       PetscInt first,step,n,rstart,rend;
7754       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7755       if (step == 1) {
7756         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7757         if (rstart == first) {
7758           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7759           if (n == rend-rstart) {
7760             grabentirematrix = 1;
7761           }
7762         }
7763       }
7764     }
7765     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7766     if (grab) {
7767       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7768       if (cll == MAT_INITIAL_MATRIX) {
7769         *newmat = mat;
7770         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7771       }
7772       PetscFunctionReturn(0);
7773     }
7774   }
7775 
7776   if (!iscol) {
7777     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7778   } else {
7779     iscoltmp = iscol;
7780   }
7781 
7782   /* if original matrix is on just one processor then use submatrix generated */
7783   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7784     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7785     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7786     PetscFunctionReturn(0);
7787   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7788     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7789     *newmat = *local;
7790     ierr    = PetscFree(local);CHKERRQ(ierr);
7791     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7792     PetscFunctionReturn(0);
7793   } else if (!mat->ops->createsubmatrix) {
7794     /* Create a new matrix type that implements the operation using the full matrix */
7795     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7796     switch (cll) {
7797     case MAT_INITIAL_MATRIX:
7798       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7799       break;
7800     case MAT_REUSE_MATRIX:
7801       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7802       break;
7803     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7804     }
7805     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7806     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7807     PetscFunctionReturn(0);
7808   }
7809 
7810   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7811   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7812   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7813   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7814   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7815   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7816   PetscFunctionReturn(0);
7817 }
7818 
7819 /*@
7820    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7821    used during the assembly process to store values that belong to
7822    other processors.
7823 
7824    Not Collective
7825 
7826    Input Parameters:
7827 +  mat   - the matrix
7828 .  size  - the initial size of the stash.
7829 -  bsize - the initial size of the block-stash(if used).
7830 
7831    Options Database Keys:
7832 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7833 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7834 
7835    Level: intermediate
7836 
7837    Notes:
7838      The block-stash is used for values set with MatSetValuesBlocked() while
7839      the stash is used for values set with MatSetValues()
7840 
7841      Run with the option -info and look for output of the form
7842      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7843      to determine the appropriate value, MM, to use for size and
7844      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7845      to determine the value, BMM to use for bsize
7846 
7847    Concepts: stash^setting matrix size
7848    Concepts: matrices^stash
7849 
7850 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7851 
7852 @*/
7853 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7854 {
7855   PetscErrorCode ierr;
7856 
7857   PetscFunctionBegin;
7858   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7859   PetscValidType(mat,1);
7860   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7861   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7862   PetscFunctionReturn(0);
7863 }
7864 
7865 /*@
7866    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7867      the matrix
7868 
7869    Neighbor-wise Collective on Mat
7870 
7871    Input Parameters:
7872 +  mat   - the matrix
7873 .  x,y - the vectors
7874 -  w - where the result is stored
7875 
7876    Level: intermediate
7877 
7878    Notes:
7879     w may be the same vector as y.
7880 
7881     This allows one to use either the restriction or interpolation (its transpose)
7882     matrix to do the interpolation
7883 
7884     Concepts: interpolation
7885 
7886 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7887 
7888 @*/
7889 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7890 {
7891   PetscErrorCode ierr;
7892   PetscInt       M,N,Ny;
7893 
7894   PetscFunctionBegin;
7895   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7896   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7897   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7898   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7899   PetscValidType(A,1);
7900   MatCheckPreallocated(A,1);
7901   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7902   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7903   if (M == Ny) {
7904     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7905   } else {
7906     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7907   }
7908   PetscFunctionReturn(0);
7909 }
7910 
7911 /*@
7912    MatInterpolate - y = A*x or A'*x depending on the shape of
7913      the matrix
7914 
7915    Neighbor-wise Collective on Mat
7916 
7917    Input Parameters:
7918 +  mat   - the matrix
7919 -  x,y - the vectors
7920 
7921    Level: intermediate
7922 
7923    Notes:
7924     This allows one to use either the restriction or interpolation (its transpose)
7925     matrix to do the interpolation
7926 
7927    Concepts: matrices^interpolation
7928 
7929 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7930 
7931 @*/
7932 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7933 {
7934   PetscErrorCode ierr;
7935   PetscInt       M,N,Ny;
7936 
7937   PetscFunctionBegin;
7938   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7939   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7940   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7941   PetscValidType(A,1);
7942   MatCheckPreallocated(A,1);
7943   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7944   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7945   if (M == Ny) {
7946     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7947   } else {
7948     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7949   }
7950   PetscFunctionReturn(0);
7951 }
7952 
7953 /*@
7954    MatRestrict - y = A*x or A'*x
7955 
7956    Neighbor-wise Collective on Mat
7957 
7958    Input Parameters:
7959 +  mat   - the matrix
7960 -  x,y - the vectors
7961 
7962    Level: intermediate
7963 
7964    Notes:
7965     This allows one to use either the restriction or interpolation (its transpose)
7966     matrix to do the restriction
7967 
7968    Concepts: matrices^restriction
7969 
7970 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7971 
7972 @*/
7973 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7974 {
7975   PetscErrorCode ierr;
7976   PetscInt       M,N,Ny;
7977 
7978   PetscFunctionBegin;
7979   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7980   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7981   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7982   PetscValidType(A,1);
7983   MatCheckPreallocated(A,1);
7984 
7985   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7986   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7987   if (M == Ny) {
7988     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7989   } else {
7990     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7991   }
7992   PetscFunctionReturn(0);
7993 }
7994 
7995 /*@C
7996    MatGetNullSpace - retrieves the null space to a matrix.
7997 
7998    Logically Collective on Mat and MatNullSpace
7999 
8000    Input Parameters:
8001 +  mat - the matrix
8002 -  nullsp - the null space object
8003 
8004    Level: developer
8005 
8006    Concepts: null space^attaching to matrix
8007 
8008 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8009 @*/
8010 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8011 {
8012   PetscFunctionBegin;
8013   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8014   PetscValidPointer(nullsp,2);
8015   *nullsp = mat->nullsp;
8016   PetscFunctionReturn(0);
8017 }
8018 
8019 /*@C
8020    MatSetNullSpace - attaches a null space to a matrix.
8021 
8022    Logically Collective on Mat and MatNullSpace
8023 
8024    Input Parameters:
8025 +  mat - the matrix
8026 -  nullsp - the null space object
8027 
8028    Level: advanced
8029 
8030    Notes:
8031       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8032 
8033       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8034       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8035 
8036       You can remove the null space by calling this routine with an nullsp of NULL
8037 
8038 
8039       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8040    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).
8041    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
8042    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
8043    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).
8044 
8045       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8046 
8047     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
8048     routine also automatically calls MatSetTransposeNullSpace().
8049 
8050    Concepts: null space^attaching to matrix
8051 
8052 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8053 @*/
8054 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8055 {
8056   PetscErrorCode ierr;
8057 
8058   PetscFunctionBegin;
8059   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8060   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8061   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8062   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8063   mat->nullsp = nullsp;
8064   if (mat->symmetric_set && mat->symmetric) {
8065     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8066   }
8067   PetscFunctionReturn(0);
8068 }
8069 
8070 /*@
8071    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8072 
8073    Logically Collective on Mat and MatNullSpace
8074 
8075    Input Parameters:
8076 +  mat - the matrix
8077 -  nullsp - the null space object
8078 
8079    Level: developer
8080 
8081    Concepts: null space^attaching to matrix
8082 
8083 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8084 @*/
8085 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8086 {
8087   PetscFunctionBegin;
8088   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8089   PetscValidType(mat,1);
8090   PetscValidPointer(nullsp,2);
8091   *nullsp = mat->transnullsp;
8092   PetscFunctionReturn(0);
8093 }
8094 
8095 /*@
8096    MatSetTransposeNullSpace - attaches a null space to a matrix.
8097 
8098    Logically Collective on Mat and MatNullSpace
8099 
8100    Input Parameters:
8101 +  mat - the matrix
8102 -  nullsp - the null space object
8103 
8104    Level: advanced
8105 
8106    Notes:
8107       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.
8108       You must also call MatSetNullSpace()
8109 
8110 
8111       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8112    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).
8113    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
8114    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
8115    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).
8116 
8117       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8118 
8119    Concepts: null space^attaching to matrix
8120 
8121 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8122 @*/
8123 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8124 {
8125   PetscErrorCode ierr;
8126 
8127   PetscFunctionBegin;
8128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8129   PetscValidType(mat,1);
8130   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8131   MatCheckPreallocated(mat,1);
8132   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8133   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8134   mat->transnullsp = nullsp;
8135   PetscFunctionReturn(0);
8136 }
8137 
8138 /*@
8139    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8140         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8141 
8142    Logically Collective on Mat and MatNullSpace
8143 
8144    Input Parameters:
8145 +  mat - the matrix
8146 -  nullsp - the null space object
8147 
8148    Level: advanced
8149 
8150    Notes:
8151       Overwrites any previous near null space that may have been attached
8152 
8153       You can remove the null space by calling this routine with an nullsp of NULL
8154 
8155    Concepts: null space^attaching to matrix
8156 
8157 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8158 @*/
8159 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8160 {
8161   PetscErrorCode ierr;
8162 
8163   PetscFunctionBegin;
8164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8165   PetscValidType(mat,1);
8166   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8167   MatCheckPreallocated(mat,1);
8168   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8169   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8170   mat->nearnullsp = nullsp;
8171   PetscFunctionReturn(0);
8172 }
8173 
8174 /*@
8175    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8176 
8177    Not Collective
8178 
8179    Input Parameters:
8180 .  mat - the matrix
8181 
8182    Output Parameters:
8183 .  nullsp - the null space object, NULL if not set
8184 
8185    Level: developer
8186 
8187    Concepts: null space^attaching to matrix
8188 
8189 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8190 @*/
8191 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8192 {
8193   PetscFunctionBegin;
8194   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8195   PetscValidType(mat,1);
8196   PetscValidPointer(nullsp,2);
8197   MatCheckPreallocated(mat,1);
8198   *nullsp = mat->nearnullsp;
8199   PetscFunctionReturn(0);
8200 }
8201 
8202 /*@C
8203    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8204 
8205    Collective on Mat
8206 
8207    Input Parameters:
8208 +  mat - the matrix
8209 .  row - row/column permutation
8210 .  fill - expected fill factor >= 1.0
8211 -  level - level of fill, for ICC(k)
8212 
8213    Notes:
8214    Probably really in-place only when level of fill is zero, otherwise allocates
8215    new space to store factored matrix and deletes previous memory.
8216 
8217    Most users should employ the simplified KSP interface for linear solvers
8218    instead of working directly with matrix algebra routines such as this.
8219    See, e.g., KSPCreate().
8220 
8221    Level: developer
8222 
8223    Concepts: matrices^incomplete Cholesky factorization
8224    Concepts: Cholesky factorization
8225 
8226 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8227 
8228     Developer Note: fortran interface is not autogenerated as the f90
8229     interface defintion cannot be generated correctly [due to MatFactorInfo]
8230 
8231 @*/
8232 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8233 {
8234   PetscErrorCode ierr;
8235 
8236   PetscFunctionBegin;
8237   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8238   PetscValidType(mat,1);
8239   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8240   PetscValidPointer(info,3);
8241   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8242   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8243   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8244   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8245   MatCheckPreallocated(mat,1);
8246   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8247   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8248   PetscFunctionReturn(0);
8249 }
8250 
8251 /*@
8252    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8253          ghosted ones.
8254 
8255    Not Collective
8256 
8257    Input Parameters:
8258 +  mat - the matrix
8259 -  diag = the diagonal values, including ghost ones
8260 
8261    Level: developer
8262 
8263    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8264 
8265 .seealso: MatDiagonalScale()
8266 @*/
8267 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8268 {
8269   PetscErrorCode ierr;
8270   PetscMPIInt    size;
8271 
8272   PetscFunctionBegin;
8273   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8274   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8275   PetscValidType(mat,1);
8276 
8277   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8278   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8279   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8280   if (size == 1) {
8281     PetscInt n,m;
8282     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8283     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8284     if (m == n) {
8285       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8286     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8287   } else {
8288     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8289   }
8290   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8291   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8292   PetscFunctionReturn(0);
8293 }
8294 
8295 /*@
8296    MatGetInertia - Gets the inertia from a factored matrix
8297 
8298    Collective on Mat
8299 
8300    Input Parameter:
8301 .  mat - the matrix
8302 
8303    Output Parameters:
8304 +   nneg - number of negative eigenvalues
8305 .   nzero - number of zero eigenvalues
8306 -   npos - number of positive eigenvalues
8307 
8308    Level: advanced
8309 
8310    Notes: Matrix must have been factored by MatCholeskyFactor()
8311 
8312 
8313 @*/
8314 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8315 {
8316   PetscErrorCode ierr;
8317 
8318   PetscFunctionBegin;
8319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8320   PetscValidType(mat,1);
8321   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8322   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8323   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8324   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8325   PetscFunctionReturn(0);
8326 }
8327 
8328 /* ----------------------------------------------------------------*/
8329 /*@C
8330    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8331 
8332    Neighbor-wise Collective on Mat and Vecs
8333 
8334    Input Parameters:
8335 +  mat - the factored matrix
8336 -  b - the right-hand-side vectors
8337 
8338    Output Parameter:
8339 .  x - the result vectors
8340 
8341    Notes:
8342    The vectors b and x cannot be the same.  I.e., one cannot
8343    call MatSolves(A,x,x).
8344 
8345    Notes:
8346    Most users should employ the simplified KSP interface for linear solvers
8347    instead of working directly with matrix algebra routines such as this.
8348    See, e.g., KSPCreate().
8349 
8350    Level: developer
8351 
8352    Concepts: matrices^triangular solves
8353 
8354 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8355 @*/
8356 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8357 {
8358   PetscErrorCode ierr;
8359 
8360   PetscFunctionBegin;
8361   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8362   PetscValidType(mat,1);
8363   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8364   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8365   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8366 
8367   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8368   MatCheckPreallocated(mat,1);
8369   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8370   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8371   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8372   PetscFunctionReturn(0);
8373 }
8374 
8375 /*@
8376    MatIsSymmetric - Test whether a matrix is symmetric
8377 
8378    Collective on Mat
8379 
8380    Input Parameter:
8381 +  A - the matrix to test
8382 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8383 
8384    Output Parameters:
8385 .  flg - the result
8386 
8387    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8388 
8389    Level: intermediate
8390 
8391    Concepts: matrix^symmetry
8392 
8393 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8394 @*/
8395 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8396 {
8397   PetscErrorCode ierr;
8398 
8399   PetscFunctionBegin;
8400   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8401   PetscValidPointer(flg,2);
8402 
8403   if (!A->symmetric_set) {
8404     if (!A->ops->issymmetric) {
8405       MatType mattype;
8406       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8407       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8408     }
8409     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8410     if (!tol) {
8411       A->symmetric_set = PETSC_TRUE;
8412       A->symmetric     = *flg;
8413       if (A->symmetric) {
8414         A->structurally_symmetric_set = PETSC_TRUE;
8415         A->structurally_symmetric     = PETSC_TRUE;
8416       }
8417     }
8418   } else if (A->symmetric) {
8419     *flg = PETSC_TRUE;
8420   } else if (!tol) {
8421     *flg = PETSC_FALSE;
8422   } else {
8423     if (!A->ops->issymmetric) {
8424       MatType mattype;
8425       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8426       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8427     }
8428     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8429   }
8430   PetscFunctionReturn(0);
8431 }
8432 
8433 /*@
8434    MatIsHermitian - Test whether a matrix is Hermitian
8435 
8436    Collective on Mat
8437 
8438    Input Parameter:
8439 +  A - the matrix to test
8440 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8441 
8442    Output Parameters:
8443 .  flg - the result
8444 
8445    Level: intermediate
8446 
8447    Concepts: matrix^symmetry
8448 
8449 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8450           MatIsSymmetricKnown(), MatIsSymmetric()
8451 @*/
8452 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8453 {
8454   PetscErrorCode ierr;
8455 
8456   PetscFunctionBegin;
8457   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8458   PetscValidPointer(flg,2);
8459 
8460   if (!A->hermitian_set) {
8461     if (!A->ops->ishermitian) {
8462       MatType mattype;
8463       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8464       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8465     }
8466     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8467     if (!tol) {
8468       A->hermitian_set = PETSC_TRUE;
8469       A->hermitian     = *flg;
8470       if (A->hermitian) {
8471         A->structurally_symmetric_set = PETSC_TRUE;
8472         A->structurally_symmetric     = PETSC_TRUE;
8473       }
8474     }
8475   } else if (A->hermitian) {
8476     *flg = PETSC_TRUE;
8477   } else if (!tol) {
8478     *flg = PETSC_FALSE;
8479   } else {
8480     if (!A->ops->ishermitian) {
8481       MatType mattype;
8482       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8483       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8484     }
8485     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8486   }
8487   PetscFunctionReturn(0);
8488 }
8489 
8490 /*@
8491    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8492 
8493    Not Collective
8494 
8495    Input Parameter:
8496 .  A - the matrix to check
8497 
8498    Output Parameters:
8499 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8500 -  flg - the result
8501 
8502    Level: advanced
8503 
8504    Concepts: matrix^symmetry
8505 
8506    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8507          if you want it explicitly checked
8508 
8509 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8510 @*/
8511 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8512 {
8513   PetscFunctionBegin;
8514   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8515   PetscValidPointer(set,2);
8516   PetscValidPointer(flg,3);
8517   if (A->symmetric_set) {
8518     *set = PETSC_TRUE;
8519     *flg = A->symmetric;
8520   } else {
8521     *set = PETSC_FALSE;
8522   }
8523   PetscFunctionReturn(0);
8524 }
8525 
8526 /*@
8527    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8528 
8529    Not Collective
8530 
8531    Input Parameter:
8532 .  A - the matrix to check
8533 
8534    Output Parameters:
8535 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8536 -  flg - the result
8537 
8538    Level: advanced
8539 
8540    Concepts: matrix^symmetry
8541 
8542    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8543          if you want it explicitly checked
8544 
8545 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8546 @*/
8547 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8548 {
8549   PetscFunctionBegin;
8550   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8551   PetscValidPointer(set,2);
8552   PetscValidPointer(flg,3);
8553   if (A->hermitian_set) {
8554     *set = PETSC_TRUE;
8555     *flg = A->hermitian;
8556   } else {
8557     *set = PETSC_FALSE;
8558   }
8559   PetscFunctionReturn(0);
8560 }
8561 
8562 /*@
8563    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8564 
8565    Collective on Mat
8566 
8567    Input Parameter:
8568 .  A - the matrix to test
8569 
8570    Output Parameters:
8571 .  flg - the result
8572 
8573    Level: intermediate
8574 
8575    Concepts: matrix^symmetry
8576 
8577 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8578 @*/
8579 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8580 {
8581   PetscErrorCode ierr;
8582 
8583   PetscFunctionBegin;
8584   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8585   PetscValidPointer(flg,2);
8586   if (!A->structurally_symmetric_set) {
8587     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8588     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8589 
8590     A->structurally_symmetric_set = PETSC_TRUE;
8591   }
8592   *flg = A->structurally_symmetric;
8593   PetscFunctionReturn(0);
8594 }
8595 
8596 /*@
8597    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8598        to be communicated to other processors during the MatAssemblyBegin/End() process
8599 
8600     Not collective
8601 
8602    Input Parameter:
8603 .   vec - the vector
8604 
8605    Output Parameters:
8606 +   nstash   - the size of the stash
8607 .   reallocs - the number of additional mallocs incurred.
8608 .   bnstash   - the size of the block stash
8609 -   breallocs - the number of additional mallocs incurred.in the block stash
8610 
8611    Level: advanced
8612 
8613 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8614 
8615 @*/
8616 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8617 {
8618   PetscErrorCode ierr;
8619 
8620   PetscFunctionBegin;
8621   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8622   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8623   PetscFunctionReturn(0);
8624 }
8625 
8626 /*@C
8627    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8628      parallel layout
8629 
8630    Collective on Mat
8631 
8632    Input Parameter:
8633 .  mat - the matrix
8634 
8635    Output Parameter:
8636 +   right - (optional) vector that the matrix can be multiplied against
8637 -   left - (optional) vector that the matrix vector product can be stored in
8638 
8639    Notes:
8640     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().
8641 
8642   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8643 
8644   Level: advanced
8645 
8646 .seealso: MatCreate(), VecDestroy()
8647 @*/
8648 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8649 {
8650   PetscErrorCode ierr;
8651 
8652   PetscFunctionBegin;
8653   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8654   PetscValidType(mat,1);
8655   if (mat->ops->getvecs) {
8656     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8657   } else {
8658     PetscInt rbs,cbs;
8659     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8660     if (right) {
8661       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8662       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8663       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8664       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8665       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8666       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8667     }
8668     if (left) {
8669       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8670       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8671       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8672       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8673       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8674       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8675     }
8676   }
8677   PetscFunctionReturn(0);
8678 }
8679 
8680 /*@C
8681    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8682      with default values.
8683 
8684    Not Collective
8685 
8686    Input Parameters:
8687 .    info - the MatFactorInfo data structure
8688 
8689 
8690    Notes: The solvers are generally used through the KSP and PC objects, for example
8691           PCLU, PCILU, PCCHOLESKY, PCICC
8692 
8693    Level: developer
8694 
8695 .seealso: MatFactorInfo
8696 
8697     Developer Note: fortran interface is not autogenerated as the f90
8698     interface defintion cannot be generated correctly [due to MatFactorInfo]
8699 
8700 @*/
8701 
8702 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8703 {
8704   PetscErrorCode ierr;
8705 
8706   PetscFunctionBegin;
8707   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8708   PetscFunctionReturn(0);
8709 }
8710 
8711 /*@
8712    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8713 
8714    Collective on Mat
8715 
8716    Input Parameters:
8717 +  mat - the factored matrix
8718 -  is - the index set defining the Schur indices (0-based)
8719 
8720    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8721 
8722    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8723 
8724    Level: developer
8725 
8726    Concepts:
8727 
8728 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8729           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8730 
8731 @*/
8732 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8733 {
8734   PetscErrorCode ierr,(*f)(Mat,IS);
8735 
8736   PetscFunctionBegin;
8737   PetscValidType(mat,1);
8738   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8739   PetscValidType(is,2);
8740   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8741   PetscCheckSameComm(mat,1,is,2);
8742   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8743   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8744   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");
8745   if (mat->schur) {
8746     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8747   }
8748   ierr = (*f)(mat,is);CHKERRQ(ierr);
8749   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8750   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8751   PetscFunctionReturn(0);
8752 }
8753 
8754 /*@
8755   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8756 
8757    Logically Collective on Mat
8758 
8759    Input Parameters:
8760 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8761 .  S - location where to return the Schur complement, can be NULL
8762 -  status - the status of the Schur complement matrix, can be NULL
8763 
8764    Notes:
8765    You must call MatFactorSetSchurIS() before calling this routine.
8766 
8767    The routine provides a copy of the Schur matrix stored within the solver data structures.
8768    The caller must destroy the object when it is no longer needed.
8769    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8770 
8771    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)
8772 
8773    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
8774    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8775 
8776    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8777 
8778    Level: advanced
8779 
8780    References:
8781 
8782 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8783 @*/
8784 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8785 {
8786   PetscErrorCode ierr;
8787 
8788   PetscFunctionBegin;
8789   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8790   if (S) PetscValidPointer(S,2);
8791   if (status) PetscValidPointer(status,3);
8792   if (S) {
8793     PetscErrorCode (*f)(Mat,Mat*);
8794 
8795     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8796     if (f) {
8797       ierr = (*f)(F,S);CHKERRQ(ierr);
8798     } else {
8799       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8800     }
8801   }
8802   if (status) *status = F->schur_status;
8803   PetscFunctionReturn(0);
8804 }
8805 
8806 /*@
8807   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8808 
8809    Logically Collective on Mat
8810 
8811    Input Parameters:
8812 +  F - the factored matrix obtained by calling MatGetFactor()
8813 .  *S - location where to return the Schur complement, can be NULL
8814 -  status - the status of the Schur complement matrix, can be NULL
8815 
8816    Notes:
8817    You must call MatFactorSetSchurIS() before calling this routine.
8818 
8819    Schur complement mode is currently implemented for sequential matrices.
8820    The routine returns a the Schur Complement stored within the data strutures of the solver.
8821    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8822    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8823 
8824    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8825 
8826    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8827 
8828    Level: advanced
8829 
8830    References:
8831 
8832 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8833 @*/
8834 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8835 {
8836   PetscFunctionBegin;
8837   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8838   if (S) PetscValidPointer(S,2);
8839   if (status) PetscValidPointer(status,3);
8840   if (S) *S = F->schur;
8841   if (status) *status = F->schur_status;
8842   PetscFunctionReturn(0);
8843 }
8844 
8845 /*@
8846   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8847 
8848    Logically Collective on Mat
8849 
8850    Input Parameters:
8851 +  F - the factored matrix obtained by calling MatGetFactor()
8852 .  *S - location where the Schur complement is stored
8853 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8854 
8855    Notes:
8856 
8857    Level: advanced
8858 
8859    References:
8860 
8861 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8862 @*/
8863 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8864 {
8865   PetscErrorCode ierr;
8866 
8867   PetscFunctionBegin;
8868   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8869   if (S) {
8870     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8871     *S = NULL;
8872   }
8873   F->schur_status = status;
8874   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8875   PetscFunctionReturn(0);
8876 }
8877 
8878 /*@
8879   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8880 
8881    Logically Collective on Mat
8882 
8883    Input Parameters:
8884 +  F - the factored matrix obtained by calling MatGetFactor()
8885 .  rhs - location where the right hand side of the Schur complement system is stored
8886 -  sol - location where the solution of the Schur complement system has to be returned
8887 
8888    Notes:
8889    The sizes of the vectors should match the size of the Schur complement
8890 
8891    Must be called after MatFactorSetSchurIS()
8892 
8893    Level: advanced
8894 
8895    References:
8896 
8897 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8898 @*/
8899 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8900 {
8901   PetscErrorCode ierr;
8902 
8903   PetscFunctionBegin;
8904   PetscValidType(F,1);
8905   PetscValidType(rhs,2);
8906   PetscValidType(sol,3);
8907   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8908   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8909   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8910   PetscCheckSameComm(F,1,rhs,2);
8911   PetscCheckSameComm(F,1,sol,3);
8912   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8913   switch (F->schur_status) {
8914   case MAT_FACTOR_SCHUR_FACTORED:
8915     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8916     break;
8917   case MAT_FACTOR_SCHUR_INVERTED:
8918     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8919     break;
8920   default:
8921     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8922     break;
8923   }
8924   PetscFunctionReturn(0);
8925 }
8926 
8927 /*@
8928   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8929 
8930    Logically Collective on Mat
8931 
8932    Input Parameters:
8933 +  F - the factored matrix obtained by calling MatGetFactor()
8934 .  rhs - location where the right hand side of the Schur complement system is stored
8935 -  sol - location where the solution of the Schur complement system has to be returned
8936 
8937    Notes:
8938    The sizes of the vectors should match the size of the Schur complement
8939 
8940    Must be called after MatFactorSetSchurIS()
8941 
8942    Level: advanced
8943 
8944    References:
8945 
8946 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
8947 @*/
8948 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8949 {
8950   PetscErrorCode ierr;
8951 
8952   PetscFunctionBegin;
8953   PetscValidType(F,1);
8954   PetscValidType(rhs,2);
8955   PetscValidType(sol,3);
8956   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8957   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8958   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8959   PetscCheckSameComm(F,1,rhs,2);
8960   PetscCheckSameComm(F,1,sol,3);
8961   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8962   switch (F->schur_status) {
8963   case MAT_FACTOR_SCHUR_FACTORED:
8964     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
8965     break;
8966   case MAT_FACTOR_SCHUR_INVERTED:
8967     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
8968     break;
8969   default:
8970     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8971     break;
8972   }
8973   PetscFunctionReturn(0);
8974 }
8975 
8976 /*@
8977   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
8978 
8979    Logically Collective on Mat
8980 
8981    Input Parameters:
8982 +  F - the factored matrix obtained by calling MatGetFactor()
8983 
8984    Notes: Must be called after MatFactorSetSchurIS().
8985 
8986    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
8987 
8988    Level: advanced
8989 
8990    References:
8991 
8992 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
8993 @*/
8994 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
8995 {
8996   PetscErrorCode ierr;
8997 
8998   PetscFunctionBegin;
8999   PetscValidType(F,1);
9000   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9001   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9002   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9003   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9004   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9005   PetscFunctionReturn(0);
9006 }
9007 
9008 /*@
9009   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9010 
9011    Logically Collective on Mat
9012 
9013    Input Parameters:
9014 +  F - the factored matrix obtained by calling MatGetFactor()
9015 
9016    Notes: Must be called after MatFactorSetSchurIS().
9017 
9018    Level: advanced
9019 
9020    References:
9021 
9022 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9023 @*/
9024 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9025 {
9026   PetscErrorCode ierr;
9027 
9028   PetscFunctionBegin;
9029   PetscValidType(F,1);
9030   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9031   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9032   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9033   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9034   PetscFunctionReturn(0);
9035 }
9036 
9037 /*@
9038    MatPtAP - Creates the matrix product C = P^T * A * P
9039 
9040    Neighbor-wise Collective on Mat
9041 
9042    Input Parameters:
9043 +  A - the matrix
9044 .  P - the projection matrix
9045 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9046 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9047           if the result is a dense matrix this is irrelevent
9048 
9049    Output Parameters:
9050 .  C - the product matrix
9051 
9052    Notes:
9053    C will be created and must be destroyed by the user with MatDestroy().
9054 
9055    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9056    which inherit from AIJ.
9057 
9058    Level: intermediate
9059 
9060 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9061 @*/
9062 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9063 {
9064   PetscErrorCode ierr;
9065   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9066   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9067   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9068 
9069   PetscFunctionBegin;
9070   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9071   PetscValidType(A,1);
9072   MatCheckPreallocated(A,1);
9073   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9074   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9075   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9076   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9077   PetscValidType(P,2);
9078   MatCheckPreallocated(P,2);
9079   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9080   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9081 
9082   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);
9083   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);
9084   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9085   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9086 
9087   if (scall == MAT_REUSE_MATRIX) {
9088     PetscValidPointer(*C,5);
9089     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9090 
9091     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9092     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9093     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9094     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9095     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9096     PetscFunctionReturn(0);
9097   }
9098 
9099   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9100   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9101 
9102   fA = A->ops->ptap;
9103   fP = P->ops->ptap;
9104   if (fP == fA) {
9105     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9106     ptap = fA;
9107   } else {
9108     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9109     char ptapname[256];
9110     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9111     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9112     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9113     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9114     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9115     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9116     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);
9117   }
9118 
9119   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9120   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9121   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9122   PetscFunctionReturn(0);
9123 }
9124 
9125 /*@
9126    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9127 
9128    Neighbor-wise Collective on Mat
9129 
9130    Input Parameters:
9131 +  A - the matrix
9132 -  P - the projection matrix
9133 
9134    Output Parameters:
9135 .  C - the product matrix
9136 
9137    Notes:
9138    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9139    the user using MatDeatroy().
9140 
9141    This routine is currently only implemented for pairs of AIJ matrices and classes
9142    which inherit from AIJ.  C will be of type MATAIJ.
9143 
9144    Level: intermediate
9145 
9146 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9147 @*/
9148 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9149 {
9150   PetscErrorCode ierr;
9151 
9152   PetscFunctionBegin;
9153   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9154   PetscValidType(A,1);
9155   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9156   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9157   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9158   PetscValidType(P,2);
9159   MatCheckPreallocated(P,2);
9160   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9161   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9162   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9163   PetscValidType(C,3);
9164   MatCheckPreallocated(C,3);
9165   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9166   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);
9167   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);
9168   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);
9169   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);
9170   MatCheckPreallocated(A,1);
9171 
9172   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9173   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9174   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9175   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9176   PetscFunctionReturn(0);
9177 }
9178 
9179 /*@
9180    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9181 
9182    Neighbor-wise Collective on Mat
9183 
9184    Input Parameters:
9185 +  A - the matrix
9186 -  P - the projection matrix
9187 
9188    Output Parameters:
9189 .  C - the (i,j) structure of the product matrix
9190 
9191    Notes:
9192    C will be created and must be destroyed by the user with MatDestroy().
9193 
9194    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9195    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9196    this (i,j) structure by calling MatPtAPNumeric().
9197 
9198    Level: intermediate
9199 
9200 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9201 @*/
9202 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9203 {
9204   PetscErrorCode ierr;
9205 
9206   PetscFunctionBegin;
9207   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9208   PetscValidType(A,1);
9209   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9210   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9211   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9212   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9213   PetscValidType(P,2);
9214   MatCheckPreallocated(P,2);
9215   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9216   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9217   PetscValidPointer(C,3);
9218 
9219   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);
9220   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);
9221   MatCheckPreallocated(A,1);
9222 
9223   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9224   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9225   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9226   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9227 
9228   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9229   PetscFunctionReturn(0);
9230 }
9231 
9232 /*@
9233    MatRARt - Creates the matrix product C = R * A * R^T
9234 
9235    Neighbor-wise Collective on Mat
9236 
9237    Input Parameters:
9238 +  A - the matrix
9239 .  R - the projection matrix
9240 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9241 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9242           if the result is a dense matrix this is irrelevent
9243 
9244    Output Parameters:
9245 .  C - the product matrix
9246 
9247    Notes:
9248    C will be created and must be destroyed by the user with MatDestroy().
9249 
9250    This routine is currently only implemented for pairs of AIJ matrices and classes
9251    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9252    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9253    We recommend using MatPtAP().
9254 
9255    Level: intermediate
9256 
9257 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9258 @*/
9259 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9260 {
9261   PetscErrorCode ierr;
9262 
9263   PetscFunctionBegin;
9264   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9265   PetscValidType(A,1);
9266   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9267   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9268   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9269   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9270   PetscValidType(R,2);
9271   MatCheckPreallocated(R,2);
9272   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9273   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9274   PetscValidPointer(C,3);
9275   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);
9276 
9277   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9278   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9279   MatCheckPreallocated(A,1);
9280 
9281   if (!A->ops->rart) {
9282     Mat Rt;
9283     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9284     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9285     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9286     PetscFunctionReturn(0);
9287   }
9288   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9289   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9290   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9291   PetscFunctionReturn(0);
9292 }
9293 
9294 /*@
9295    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9296 
9297    Neighbor-wise Collective on Mat
9298 
9299    Input Parameters:
9300 +  A - the matrix
9301 -  R - the projection matrix
9302 
9303    Output Parameters:
9304 .  C - the product matrix
9305 
9306    Notes:
9307    C must have been created by calling MatRARtSymbolic and must be destroyed by
9308    the user using MatDestroy().
9309 
9310    This routine is currently only implemented for pairs of AIJ matrices and classes
9311    which inherit from AIJ.  C will be of type MATAIJ.
9312 
9313    Level: intermediate
9314 
9315 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9316 @*/
9317 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9318 {
9319   PetscErrorCode ierr;
9320 
9321   PetscFunctionBegin;
9322   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9323   PetscValidType(A,1);
9324   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9325   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9326   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9327   PetscValidType(R,2);
9328   MatCheckPreallocated(R,2);
9329   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9330   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9331   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9332   PetscValidType(C,3);
9333   MatCheckPreallocated(C,3);
9334   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9335   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);
9336   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);
9337   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);
9338   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);
9339   MatCheckPreallocated(A,1);
9340 
9341   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9342   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9343   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9344   PetscFunctionReturn(0);
9345 }
9346 
9347 /*@
9348    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9349 
9350    Neighbor-wise Collective on Mat
9351 
9352    Input Parameters:
9353 +  A - the matrix
9354 -  R - the projection matrix
9355 
9356    Output Parameters:
9357 .  C - the (i,j) structure of the product matrix
9358 
9359    Notes:
9360    C will be created and must be destroyed by the user with MatDestroy().
9361 
9362    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9363    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9364    this (i,j) structure by calling MatRARtNumeric().
9365 
9366    Level: intermediate
9367 
9368 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9369 @*/
9370 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9371 {
9372   PetscErrorCode ierr;
9373 
9374   PetscFunctionBegin;
9375   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9376   PetscValidType(A,1);
9377   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9378   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9379   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9380   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9381   PetscValidType(R,2);
9382   MatCheckPreallocated(R,2);
9383   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9384   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9385   PetscValidPointer(C,3);
9386 
9387   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);
9388   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);
9389   MatCheckPreallocated(A,1);
9390   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9391   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9392   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9393 
9394   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9395   PetscFunctionReturn(0);
9396 }
9397 
9398 /*@
9399    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9400 
9401    Neighbor-wise Collective on Mat
9402 
9403    Input Parameters:
9404 +  A - the left matrix
9405 .  B - the right matrix
9406 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9407 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9408           if the result is a dense matrix this is irrelevent
9409 
9410    Output Parameters:
9411 .  C - the product matrix
9412 
9413    Notes:
9414    Unless scall is MAT_REUSE_MATRIX C will be created.
9415 
9416    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
9417    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9418 
9419    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9420    actually needed.
9421 
9422    If you have many matrices with the same non-zero structure to multiply, you
9423    should either
9424 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9425 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9426    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
9427    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9428 
9429    Level: intermediate
9430 
9431 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9432 @*/
9433 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9434 {
9435   PetscErrorCode ierr;
9436   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9437   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9438   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9439 
9440   PetscFunctionBegin;
9441   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9442   PetscValidType(A,1);
9443   MatCheckPreallocated(A,1);
9444   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9445   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9446   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9447   PetscValidType(B,2);
9448   MatCheckPreallocated(B,2);
9449   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9450   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9451   PetscValidPointer(C,3);
9452   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9453   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);
9454   if (scall == MAT_REUSE_MATRIX) {
9455     PetscValidPointer(*C,5);
9456     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9457     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9458     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9459     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9460     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9461     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9462     PetscFunctionReturn(0);
9463   }
9464   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9465   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9466 
9467   fA = A->ops->matmult;
9468   fB = B->ops->matmult;
9469   if (fB == fA) {
9470     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9471     mult = fB;
9472   } else {
9473     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9474     char multname[256];
9475     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9476     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9477     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9478     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9479     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9480     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9481     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);
9482   }
9483   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9484   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9485   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9486   PetscFunctionReturn(0);
9487 }
9488 
9489 /*@
9490    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9491    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9492 
9493    Neighbor-wise Collective on Mat
9494 
9495    Input Parameters:
9496 +  A - the left matrix
9497 .  B - the right matrix
9498 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9499       if C is a dense matrix this is irrelevent
9500 
9501    Output Parameters:
9502 .  C - the product matrix
9503 
9504    Notes:
9505    Unless scall is MAT_REUSE_MATRIX C will be created.
9506 
9507    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9508    actually needed.
9509 
9510    This routine is currently implemented for
9511     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9512     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9513     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9514 
9515    Level: intermediate
9516 
9517    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9518      We should incorporate them into PETSc.
9519 
9520 .seealso: MatMatMult(), MatMatMultNumeric()
9521 @*/
9522 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9523 {
9524   PetscErrorCode ierr;
9525   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9526   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9527   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9528 
9529   PetscFunctionBegin;
9530   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9531   PetscValidType(A,1);
9532   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9533   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9534 
9535   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9536   PetscValidType(B,2);
9537   MatCheckPreallocated(B,2);
9538   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9539   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9540   PetscValidPointer(C,3);
9541 
9542   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);
9543   if (fill == PETSC_DEFAULT) fill = 2.0;
9544   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9545   MatCheckPreallocated(A,1);
9546 
9547   Asymbolic = A->ops->matmultsymbolic;
9548   Bsymbolic = B->ops->matmultsymbolic;
9549   if (Asymbolic == Bsymbolic) {
9550     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9551     symbolic = Bsymbolic;
9552   } else { /* dispatch based on the type of A and B */
9553     char symbolicname[256];
9554     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9555     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9556     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9557     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9558     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9559     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9560     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);
9561   }
9562   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9563   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9564   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9565   PetscFunctionReturn(0);
9566 }
9567 
9568 /*@
9569    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9570    Call this routine after first calling MatMatMultSymbolic().
9571 
9572    Neighbor-wise Collective on Mat
9573 
9574    Input Parameters:
9575 +  A - the left matrix
9576 -  B - the right matrix
9577 
9578    Output Parameters:
9579 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9580 
9581    Notes:
9582    C must have been created with MatMatMultSymbolic().
9583 
9584    This routine is currently implemented for
9585     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9586     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9587     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9588 
9589    Level: intermediate
9590 
9591 .seealso: MatMatMult(), MatMatMultSymbolic()
9592 @*/
9593 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9594 {
9595   PetscErrorCode ierr;
9596 
9597   PetscFunctionBegin;
9598   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9599   PetscFunctionReturn(0);
9600 }
9601 
9602 /*@
9603    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9604 
9605    Neighbor-wise Collective on Mat
9606 
9607    Input Parameters:
9608 +  A - the left matrix
9609 .  B - the right matrix
9610 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9611 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9612 
9613    Output Parameters:
9614 .  C - the product matrix
9615 
9616    Notes:
9617    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9618 
9619    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9620 
9621   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9622    actually needed.
9623 
9624    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9625 
9626    Level: intermediate
9627 
9628 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9629 @*/
9630 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9631 {
9632   PetscErrorCode ierr;
9633   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9634   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9635 
9636   PetscFunctionBegin;
9637   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9638   PetscValidType(A,1);
9639   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9640   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9641   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9642   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9643   PetscValidType(B,2);
9644   MatCheckPreallocated(B,2);
9645   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9646   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9647   PetscValidPointer(C,3);
9648   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);
9649   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9650   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9651   MatCheckPreallocated(A,1);
9652 
9653   fA = A->ops->mattransposemult;
9654   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9655   fB = B->ops->mattransposemult;
9656   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9657   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);
9658 
9659   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9660   if (scall == MAT_INITIAL_MATRIX) {
9661     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9662     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9663     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9664   }
9665   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9666   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9667   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9668   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9669   PetscFunctionReturn(0);
9670 }
9671 
9672 /*@
9673    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9674 
9675    Neighbor-wise Collective on Mat
9676 
9677    Input Parameters:
9678 +  A - the left matrix
9679 .  B - the right matrix
9680 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9681 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9682 
9683    Output Parameters:
9684 .  C - the product matrix
9685 
9686    Notes:
9687    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9688 
9689    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9690 
9691   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9692    actually needed.
9693 
9694    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9695    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9696 
9697    Level: intermediate
9698 
9699 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9700 @*/
9701 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9702 {
9703   PetscErrorCode ierr;
9704   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9705   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9706   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9707 
9708   PetscFunctionBegin;
9709   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9710   PetscValidType(A,1);
9711   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9712   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9713   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9714   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9715   PetscValidType(B,2);
9716   MatCheckPreallocated(B,2);
9717   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9718   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9719   PetscValidPointer(C,3);
9720   if (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);
9721   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9722   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9723   MatCheckPreallocated(A,1);
9724 
9725   fA = A->ops->transposematmult;
9726   fB = B->ops->transposematmult;
9727   if (fB==fA) {
9728     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9729     transposematmult = fA;
9730   } else {
9731     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9732     char multname[256];
9733     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9734     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9735     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9736     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9737     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9738     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9739     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);
9740   }
9741   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9742   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9743   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9744   PetscFunctionReturn(0);
9745 }
9746 
9747 /*@
9748    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9749 
9750    Neighbor-wise Collective on Mat
9751 
9752    Input Parameters:
9753 +  A - the left matrix
9754 .  B - the middle matrix
9755 .  C - the right matrix
9756 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9757 -  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
9758           if the result is a dense matrix this is irrelevent
9759 
9760    Output Parameters:
9761 .  D - the product matrix
9762 
9763    Notes:
9764    Unless scall is MAT_REUSE_MATRIX D will be created.
9765 
9766    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9767 
9768    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9769    actually needed.
9770 
9771    If you have many matrices with the same non-zero structure to multiply, you
9772    should use MAT_REUSE_MATRIX in all calls but the first or
9773 
9774    Level: intermediate
9775 
9776 .seealso: MatMatMult, MatPtAP()
9777 @*/
9778 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9779 {
9780   PetscErrorCode ierr;
9781   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9782   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9783   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9784   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9785 
9786   PetscFunctionBegin;
9787   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9788   PetscValidType(A,1);
9789   MatCheckPreallocated(A,1);
9790   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9791   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9792   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9793   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9794   PetscValidType(B,2);
9795   MatCheckPreallocated(B,2);
9796   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9797   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9798   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9799   PetscValidPointer(C,3);
9800   MatCheckPreallocated(C,3);
9801   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9802   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9803   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);
9804   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);
9805   if (scall == MAT_REUSE_MATRIX) {
9806     PetscValidPointer(*D,6);
9807     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9808     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9809     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9810     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9811     PetscFunctionReturn(0);
9812   }
9813   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9814   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9815 
9816   fA = A->ops->matmatmult;
9817   fB = B->ops->matmatmult;
9818   fC = C->ops->matmatmult;
9819   if (fA == fB && fA == fC) {
9820     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9821     mult = fA;
9822   } else {
9823     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9824     char multname[256];
9825     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9826     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9827     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9828     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9829     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9830     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9831     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9832     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9833     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);
9834   }
9835   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9836   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9837   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9838   PetscFunctionReturn(0);
9839 }
9840 
9841 /*@
9842    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9843 
9844    Collective on Mat
9845 
9846    Input Parameters:
9847 +  mat - the matrix
9848 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9849 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9850 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9851 
9852    Output Parameter:
9853 .  matredundant - redundant matrix
9854 
9855    Notes:
9856    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9857    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9858 
9859    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9860    calling it.
9861 
9862    Level: advanced
9863 
9864    Concepts: subcommunicator
9865    Concepts: duplicate matrix
9866 
9867 .seealso: MatDestroy()
9868 @*/
9869 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9870 {
9871   PetscErrorCode ierr;
9872   MPI_Comm       comm;
9873   PetscMPIInt    size;
9874   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9875   Mat_Redundant  *redund=NULL;
9876   PetscSubcomm   psubcomm=NULL;
9877   MPI_Comm       subcomm_in=subcomm;
9878   Mat            *matseq;
9879   IS             isrow,iscol;
9880   PetscBool      newsubcomm=PETSC_FALSE;
9881 
9882   PetscFunctionBegin;
9883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9884   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9885     PetscValidPointer(*matredundant,5);
9886     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9887   }
9888 
9889   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9890   if (size == 1 || nsubcomm == 1) {
9891     if (reuse == MAT_INITIAL_MATRIX) {
9892       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9893     } else {
9894       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");
9895       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9896     }
9897     PetscFunctionReturn(0);
9898   }
9899 
9900   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9901   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9902   MatCheckPreallocated(mat,1);
9903 
9904   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9905   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9906     /* create psubcomm, then get subcomm */
9907     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9908     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9909     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9910 
9911     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9912     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9913     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9914     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9915     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9916     newsubcomm = PETSC_TRUE;
9917     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9918   }
9919 
9920   /* get isrow, iscol and a local sequential matrix matseq[0] */
9921   if (reuse == MAT_INITIAL_MATRIX) {
9922     mloc_sub = PETSC_DECIDE;
9923     nloc_sub = PETSC_DECIDE;
9924     if (bs < 1) {
9925       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9926       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9927     } else {
9928       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9929       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
9930     }
9931     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9932     rstart = rend - mloc_sub;
9933     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9934     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9935   } else { /* reuse == MAT_REUSE_MATRIX */
9936     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");
9937     /* retrieve subcomm */
9938     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9939     redund = (*matredundant)->redundant;
9940     isrow  = redund->isrow;
9941     iscol  = redund->iscol;
9942     matseq = redund->matseq;
9943   }
9944   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9945 
9946   /* get matredundant over subcomm */
9947   if (reuse == MAT_INITIAL_MATRIX) {
9948     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
9949 
9950     /* create a supporting struct and attach it to C for reuse */
9951     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9952     (*matredundant)->redundant = redund;
9953     redund->isrow              = isrow;
9954     redund->iscol              = iscol;
9955     redund->matseq             = matseq;
9956     if (newsubcomm) {
9957       redund->subcomm          = subcomm;
9958     } else {
9959       redund->subcomm          = MPI_COMM_NULL;
9960     }
9961   } else {
9962     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
9963   }
9964   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9965   PetscFunctionReturn(0);
9966 }
9967 
9968 /*@C
9969    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9970    a given 'mat' object. Each submatrix can span multiple procs.
9971 
9972    Collective on Mat
9973 
9974    Input Parameters:
9975 +  mat - the matrix
9976 .  subcomm - the subcommunicator obtained by com_split(comm)
9977 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9978 
9979    Output Parameter:
9980 .  subMat - 'parallel submatrices each spans a given subcomm
9981 
9982   Notes:
9983   The submatrix partition across processors is dictated by 'subComm' a
9984   communicator obtained by com_split(comm). The comm_split
9985   is not restriced to be grouped with consecutive original ranks.
9986 
9987   Due the comm_split() usage, the parallel layout of the submatrices
9988   map directly to the layout of the original matrix [wrt the local
9989   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9990   into the 'DiagonalMat' of the subMat, hence it is used directly from
9991   the subMat. However the offDiagMat looses some columns - and this is
9992   reconstructed with MatSetValues()
9993 
9994   Level: advanced
9995 
9996   Concepts: subcommunicator
9997   Concepts: submatrices
9998 
9999 .seealso: MatCreateSubMatrices()
10000 @*/
10001 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10002 {
10003   PetscErrorCode ierr;
10004   PetscMPIInt    commsize,subCommSize;
10005 
10006   PetscFunctionBegin;
10007   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10008   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10009   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10010 
10011   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");
10012   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10013   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10014   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10015   PetscFunctionReturn(0);
10016 }
10017 
10018 /*@
10019    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10020 
10021    Not Collective
10022 
10023    Input Arguments:
10024    mat - matrix to extract local submatrix from
10025    isrow - local row indices for submatrix
10026    iscol - local column indices for submatrix
10027 
10028    Output Arguments:
10029    submat - the submatrix
10030 
10031    Level: intermediate
10032 
10033    Notes:
10034    The submat should be returned with MatRestoreLocalSubMatrix().
10035 
10036    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10037    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10038 
10039    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10040    MatSetValuesBlockedLocal() will also be implemented.
10041 
10042    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10043    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10044 
10045 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10046 @*/
10047 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10048 {
10049   PetscErrorCode ierr;
10050 
10051   PetscFunctionBegin;
10052   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10053   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10054   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10055   PetscCheckSameComm(isrow,2,iscol,3);
10056   PetscValidPointer(submat,4);
10057   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10058 
10059   if (mat->ops->getlocalsubmatrix) {
10060     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10061   } else {
10062     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10063   }
10064   PetscFunctionReturn(0);
10065 }
10066 
10067 /*@
10068    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10069 
10070    Not Collective
10071 
10072    Input Arguments:
10073    mat - matrix to extract local submatrix from
10074    isrow - local row indices for submatrix
10075    iscol - local column indices for submatrix
10076    submat - the submatrix
10077 
10078    Level: intermediate
10079 
10080 .seealso: MatGetLocalSubMatrix()
10081 @*/
10082 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10083 {
10084   PetscErrorCode ierr;
10085 
10086   PetscFunctionBegin;
10087   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10088   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10089   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10090   PetscCheckSameComm(isrow,2,iscol,3);
10091   PetscValidPointer(submat,4);
10092   if (*submat) {
10093     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10094   }
10095 
10096   if (mat->ops->restorelocalsubmatrix) {
10097     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10098   } else {
10099     ierr = MatDestroy(submat);CHKERRQ(ierr);
10100   }
10101   *submat = NULL;
10102   PetscFunctionReturn(0);
10103 }
10104 
10105 /* --------------------------------------------------------*/
10106 /*@
10107    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10108 
10109    Collective on Mat
10110 
10111    Input Parameter:
10112 .  mat - the matrix
10113 
10114    Output Parameter:
10115 .  is - if any rows have zero diagonals this contains the list of them
10116 
10117    Level: developer
10118 
10119    Concepts: matrix-vector product
10120 
10121 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10122 @*/
10123 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10124 {
10125   PetscErrorCode ierr;
10126 
10127   PetscFunctionBegin;
10128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10129   PetscValidType(mat,1);
10130   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10131   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10132 
10133   if (!mat->ops->findzerodiagonals) {
10134     Vec                diag;
10135     const PetscScalar *a;
10136     PetscInt          *rows;
10137     PetscInt           rStart, rEnd, r, nrow = 0;
10138 
10139     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10140     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10141     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10142     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10143     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10144     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10145     nrow = 0;
10146     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10147     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10148     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10149     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10150   } else {
10151     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10152   }
10153   PetscFunctionReturn(0);
10154 }
10155 
10156 /*@
10157    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10158 
10159    Collective on Mat
10160 
10161    Input Parameter:
10162 .  mat - the matrix
10163 
10164    Output Parameter:
10165 .  is - contains the list of rows with off block diagonal entries
10166 
10167    Level: developer
10168 
10169    Concepts: matrix-vector product
10170 
10171 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10172 @*/
10173 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10174 {
10175   PetscErrorCode ierr;
10176 
10177   PetscFunctionBegin;
10178   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10179   PetscValidType(mat,1);
10180   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10181   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10182 
10183   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10184   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10185   PetscFunctionReturn(0);
10186 }
10187 
10188 /*@C
10189   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10190 
10191   Collective on Mat
10192 
10193   Input Parameters:
10194 . mat - the matrix
10195 
10196   Output Parameters:
10197 . values - the block inverses in column major order (FORTRAN-like)
10198 
10199    Note:
10200    This routine is not available from Fortran.
10201 
10202   Level: advanced
10203 
10204 .seealso: MatInvertBockDiagonalMat
10205 @*/
10206 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10207 {
10208   PetscErrorCode ierr;
10209 
10210   PetscFunctionBegin;
10211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10212   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10213   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10214   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10215   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10216   PetscFunctionReturn(0);
10217 }
10218 
10219 /*@
10220   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10221 
10222   Collective on Mat
10223 
10224   Input Parameters:
10225 . A - the matrix
10226 
10227   Output Parameters:
10228 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10229 
10230   Level: advanced
10231 
10232 .seealso: MatInvertBockDiagonal()
10233 @*/
10234 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10235 {
10236   PetscErrorCode     ierr;
10237   const PetscScalar *vals;
10238   PetscInt          *dnnz;
10239   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10240 
10241   PetscFunctionBegin;
10242   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10243   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10244   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10245   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10246   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10247   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10248   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10249   for(j = 0; j < m/bs; j++) {
10250     dnnz[j] = 1;
10251   }
10252   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10253   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10254   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10255   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10256   for (i = rstart/bs; i < rend/bs; i++) {
10257     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10258   }
10259   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10260   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10261   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10262   PetscFunctionReturn(0);
10263 }
10264 
10265 /*@C
10266     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10267     via MatTransposeColoringCreate().
10268 
10269     Collective on MatTransposeColoring
10270 
10271     Input Parameter:
10272 .   c - coloring context
10273 
10274     Level: intermediate
10275 
10276 .seealso: MatTransposeColoringCreate()
10277 @*/
10278 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10279 {
10280   PetscErrorCode       ierr;
10281   MatTransposeColoring matcolor=*c;
10282 
10283   PetscFunctionBegin;
10284   if (!matcolor) PetscFunctionReturn(0);
10285   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10286 
10287   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10288   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10289   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10290   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10291   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10292   if (matcolor->brows>0) {
10293     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10294   }
10295   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10296   PetscFunctionReturn(0);
10297 }
10298 
10299 /*@C
10300     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10301     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10302     MatTransposeColoring to sparse B.
10303 
10304     Collective on MatTransposeColoring
10305 
10306     Input Parameters:
10307 +   B - sparse matrix B
10308 .   Btdense - symbolic dense matrix B^T
10309 -   coloring - coloring context created with MatTransposeColoringCreate()
10310 
10311     Output Parameter:
10312 .   Btdense - dense matrix B^T
10313 
10314     Level: advanced
10315 
10316      Notes: These are used internally for some implementations of MatRARt()
10317 
10318 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10319 
10320 .keywords: coloring
10321 @*/
10322 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10323 {
10324   PetscErrorCode ierr;
10325 
10326   PetscFunctionBegin;
10327   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10328   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10329   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10330 
10331   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10332   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10333   PetscFunctionReturn(0);
10334 }
10335 
10336 /*@C
10337     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10338     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10339     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10340     Csp from Cden.
10341 
10342     Collective on MatTransposeColoring
10343 
10344     Input Parameters:
10345 +   coloring - coloring context created with MatTransposeColoringCreate()
10346 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10347 
10348     Output Parameter:
10349 .   Csp - sparse matrix
10350 
10351     Level: advanced
10352 
10353      Notes: These are used internally for some implementations of MatRARt()
10354 
10355 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10356 
10357 .keywords: coloring
10358 @*/
10359 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10360 {
10361   PetscErrorCode ierr;
10362 
10363   PetscFunctionBegin;
10364   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10365   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10366   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10367 
10368   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10369   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10370   PetscFunctionReturn(0);
10371 }
10372 
10373 /*@C
10374    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10375 
10376    Collective on Mat
10377 
10378    Input Parameters:
10379 +  mat - the matrix product C
10380 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10381 
10382     Output Parameter:
10383 .   color - the new coloring context
10384 
10385     Level: intermediate
10386 
10387 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10388            MatTransColoringApplyDenToSp()
10389 @*/
10390 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10391 {
10392   MatTransposeColoring c;
10393   MPI_Comm             comm;
10394   PetscErrorCode       ierr;
10395 
10396   PetscFunctionBegin;
10397   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10398   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10399   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10400 
10401   c->ctype = iscoloring->ctype;
10402   if (mat->ops->transposecoloringcreate) {
10403     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10404   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10405 
10406   *color = c;
10407   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10408   PetscFunctionReturn(0);
10409 }
10410 
10411 /*@
10412       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10413         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10414         same, otherwise it will be larger
10415 
10416      Not Collective
10417 
10418   Input Parameter:
10419 .    A  - the matrix
10420 
10421   Output Parameter:
10422 .    state - the current state
10423 
10424   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10425          different matrices
10426 
10427   Level: intermediate
10428 
10429 @*/
10430 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10431 {
10432   PetscFunctionBegin;
10433   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10434   *state = mat->nonzerostate;
10435   PetscFunctionReturn(0);
10436 }
10437 
10438 /*@
10439       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10440                  matrices from each processor
10441 
10442     Collective on MPI_Comm
10443 
10444    Input Parameters:
10445 +    comm - the communicators the parallel matrix will live on
10446 .    seqmat - the input sequential matrices
10447 .    n - number of local columns (or PETSC_DECIDE)
10448 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10449 
10450    Output Parameter:
10451 .    mpimat - the parallel matrix generated
10452 
10453     Level: advanced
10454 
10455    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10456 
10457 @*/
10458 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10459 {
10460   PetscErrorCode ierr;
10461 
10462   PetscFunctionBegin;
10463   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10464   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");
10465 
10466   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10467   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10468   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10469   PetscFunctionReturn(0);
10470 }
10471 
10472 /*@
10473      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10474                  ranks' ownership ranges.
10475 
10476     Collective on A
10477 
10478    Input Parameters:
10479 +    A   - the matrix to create subdomains from
10480 -    N   - requested number of subdomains
10481 
10482 
10483    Output Parameters:
10484 +    n   - number of subdomains resulting on this rank
10485 -    iss - IS list with indices of subdomains on this rank
10486 
10487     Level: advanced
10488 
10489     Notes: number of subdomains must be smaller than the communicator size
10490 @*/
10491 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10492 {
10493   MPI_Comm        comm,subcomm;
10494   PetscMPIInt     size,rank,color;
10495   PetscInt        rstart,rend,k;
10496   PetscErrorCode  ierr;
10497 
10498   PetscFunctionBegin;
10499   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10500   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10501   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10502   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);
10503   *n = 1;
10504   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10505   color = rank/k;
10506   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10507   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10508   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10509   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10510   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10511   PetscFunctionReturn(0);
10512 }
10513 
10514 /*@
10515    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10516 
10517    If the interpolation and restriction operators are the same, uses MatPtAP.
10518    If they are not the same, use MatMatMatMult.
10519 
10520    Once the coarse grid problem is constructed, correct for interpolation operators
10521    that are not of full rank, which can legitimately happen in the case of non-nested
10522    geometric multigrid.
10523 
10524    Input Parameters:
10525 +  restrct - restriction operator
10526 .  dA - fine grid matrix
10527 .  interpolate - interpolation operator
10528 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10529 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10530 
10531    Output Parameters:
10532 .  A - the Galerkin coarse matrix
10533 
10534    Options Database Key:
10535 .  -pc_mg_galerkin <both,pmat,mat,none>
10536 
10537    Level: developer
10538 
10539 .keywords: MG, multigrid, Galerkin
10540 
10541 .seealso: MatPtAP(), MatMatMatMult()
10542 @*/
10543 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10544 {
10545   PetscErrorCode ierr;
10546   IS             zerorows;
10547   Vec            diag;
10548 
10549   PetscFunctionBegin;
10550   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10551   /* Construct the coarse grid matrix */
10552   if (interpolate == restrct) {
10553     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10554   } else {
10555     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10556   }
10557 
10558   /* If the interpolation matrix is not of full rank, A will have zero rows.
10559      This can legitimately happen in the case of non-nested geometric multigrid.
10560      In that event, we set the rows of the matrix to the rows of the identity,
10561      ignoring the equations (as the RHS will also be zero). */
10562 
10563   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10564 
10565   if (zerorows != NULL) { /* if there are any zero rows */
10566     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10567     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10568     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10569     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10570     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10571     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10572   }
10573   PetscFunctionReturn(0);
10574 }
10575 
10576 /*@C
10577     MatSetOperation - Allows user to set a matrix operation for any matrix type
10578 
10579    Logically Collective on Mat
10580 
10581     Input Parameters:
10582 +   mat - the matrix
10583 .   op - the name of the operation
10584 -   f - the function that provides the operation
10585 
10586    Level: developer
10587 
10588     Usage:
10589 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10590 $      ierr = MatCreateXXX(comm,...&A);
10591 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10592 
10593     Notes:
10594     See the file include/petscmat.h for a complete list of matrix
10595     operations, which all have the form MATOP_<OPERATION>, where
10596     <OPERATION> is the name (in all capital letters) of the
10597     user interface routine (e.g., MatMult() -> MATOP_MULT).
10598 
10599     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10600     sequence as the usual matrix interface routines, since they
10601     are intended to be accessed via the usual matrix interface
10602     routines, e.g.,
10603 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10604 
10605     In particular each function MUST return an error code of 0 on success and
10606     nonzero on failure.
10607 
10608     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10609 
10610 .keywords: matrix, set, operation
10611 
10612 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10613 @*/
10614 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10615 {
10616   PetscFunctionBegin;
10617   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10618   if (op == MATOP_VIEW && !mat->ops->viewnative) {
10619     mat->ops->viewnative = mat->ops->view;
10620   }
10621   (((void(**)(void))mat->ops)[op]) = f;
10622   PetscFunctionReturn(0);
10623 }
10624 
10625 /*@C
10626     MatGetOperation - Gets a matrix operation for any matrix type.
10627 
10628     Not Collective
10629 
10630     Input Parameters:
10631 +   mat - the matrix
10632 -   op - the name of the operation
10633 
10634     Output Parameter:
10635 .   f - the function that provides the operation
10636 
10637     Level: developer
10638 
10639     Usage:
10640 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10641 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10642 
10643     Notes:
10644     See the file include/petscmat.h for a complete list of matrix
10645     operations, which all have the form MATOP_<OPERATION>, where
10646     <OPERATION> is the name (in all capital letters) of the
10647     user interface routine (e.g., MatMult() -> MATOP_MULT).
10648 
10649     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10650 
10651 .keywords: matrix, get, operation
10652 
10653 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10654 @*/
10655 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10656 {
10657   PetscFunctionBegin;
10658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10659   *f = (((void (**)(void))mat->ops)[op]);
10660   PetscFunctionReturn(0);
10661 }
10662 
10663 /*@
10664     MatHasOperation - Determines whether the given matrix supports the particular
10665     operation.
10666 
10667    Not Collective
10668 
10669    Input Parameters:
10670 +  mat - the matrix
10671 -  op - the operation, for example, MATOP_GET_DIAGONAL
10672 
10673    Output Parameter:
10674 .  has - either PETSC_TRUE or PETSC_FALSE
10675 
10676    Level: advanced
10677 
10678    Notes:
10679    See the file include/petscmat.h for a complete list of matrix
10680    operations, which all have the form MATOP_<OPERATION>, where
10681    <OPERATION> is the name (in all capital letters) of the
10682    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10683 
10684 .keywords: matrix, has, operation
10685 
10686 .seealso: MatCreateShell()
10687 @*/
10688 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10689 {
10690   PetscErrorCode ierr;
10691 
10692   PetscFunctionBegin;
10693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10694   PetscValidType(mat,1);
10695   PetscValidPointer(has,3);
10696   if (mat->ops->hasoperation) {
10697     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10698   } else {
10699     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10700     else {
10701       *has = PETSC_FALSE;
10702       if (op == MATOP_CREATE_SUBMATRIX) {
10703         PetscMPIInt size;
10704 
10705         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10706         if (size == 1) {
10707           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10708         }
10709       }
10710     }
10711   }
10712   PetscFunctionReturn(0);
10713 }
10714