xref: /petsc/src/mat/interface/matrix.c (revision 494d6506d0ab4d3be3a715911f3ee2fb74d72b0b)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!rctx) {
80     MPI_Comm comm;
81     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
82     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
83     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
84     rctx = randObj;
85   }
86 
87   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
88   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
89   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90 
91   x->assembled = PETSC_TRUE;
92   ierr         = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
93   PetscFunctionReturn(0);
94 }
95 
96 /*@
97    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
98 
99    Logically Collective on Mat
100 
101    Input Parameters:
102 .  mat - the factored matrix
103 
104    Output Parameter:
105 +  pivot - the pivot value computed
106 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
107          the share the matrix
108 
109    Level: advanced
110 
111    Notes: This routine does not work for factorizations done with external packages.
112    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
113 
114    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
115 
116 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
117 @*/
118 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
119 {
120   PetscFunctionBegin;
121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
122   *pivot = mat->factorerror_zeropivot_value;
123   *row   = mat->factorerror_zeropivot_row;
124   PetscFunctionReturn(0);
125 }
126 
127 /*@
128    MatFactorGetError - gets the error code from a factorization
129 
130    Logically Collective on Mat
131 
132    Input Parameters:
133 .  mat - the factored matrix
134 
135    Output Parameter:
136 .  err  - the error code
137 
138    Level: advanced
139 
140    Notes:    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
141 
142 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
143 @*/
144 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
145 {
146   PetscFunctionBegin;
147   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
148   *err = mat->factorerrortype;
149   PetscFunctionReturn(0);
150 }
151 
152 /*@
153    MatFactorClearError - clears the error code in a factorization
154 
155    Logically Collective on Mat
156 
157    Input Parameter:
158 .  mat - the factored matrix
159 
160    Level: developer
161 
162    Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
163 
164 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
165 @*/
166 PetscErrorCode MatFactorClearError(Mat mat)
167 {
168   PetscFunctionBegin;
169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
170   mat->factorerrortype             = MAT_FACTOR_NOERROR;
171   mat->factorerror_zeropivot_value = 0.0;
172   mat->factorerror_zeropivot_row   = 0;
173   PetscFunctionReturn(0);
174 }
175 
176 static PetscErrorCode MatFindNonzeroRows_Basic(Mat mat,IS *keptrows)
177 {
178   PetscErrorCode    ierr;
179   Vec               r,l;
180   const PetscScalar *al;
181   PetscInt          i,nz,gnz,N,n;
182 
183   PetscFunctionBegin;
184   ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
185   ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
186   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
187   ierr = VecSet(l,0.0);CHKERRQ(ierr);
188   ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
189   ierr = MatMult(mat,r,l);CHKERRQ(ierr);
190   ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
191   for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++;
192   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
193   if (gnz != N) {
194     PetscInt *nzr;
195     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
196     if (nz) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
197     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
198   } else *keptrows = NULL;
199   ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
200   ierr = VecDestroy(&l);CHKERRQ(ierr);
201   ierr = VecDestroy(&r);CHKERRQ(ierr);
202   PetscFunctionReturn(0);
203 }
204 
205 /*@
206       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
207 
208   Input Parameter:
209 .    A  - the matrix
210 
211   Output Parameter:
212 .    keptrows - the rows that are not completely zero
213 
214   Notes: keptrows is set to NULL if all rows are nonzero.
215 
216   Level: intermediate
217 
218  @*/
219 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
220 {
221   PetscErrorCode ierr;
222 
223   PetscFunctionBegin;
224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
225   PetscValidType(mat,1);
226   PetscValidPointer(keptrows,2);
227   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
228   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
229   if (!mat->ops->findnonzerorows) {
230     ierr = MatFindNonzeroRows_Basic(mat,keptrows);CHKERRQ(ierr);
231   } else {
232     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
233   }
234   PetscFunctionReturn(0);
235 }
236 
237 /*@
238       MatFindZeroRows - Locate all rows that are completely zero in the matrix
239 
240   Input Parameter:
241 .    A  - the matrix
242 
243   Output Parameter:
244 .    zerorows - the rows that are completely zero
245 
246   Notes: zerorows is set to NULL if no rows are zero.
247 
248   Level: intermediate
249 
250  @*/
251 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
252 {
253   PetscErrorCode ierr;
254   IS keptrows;
255   PetscInt m, n;
256 
257   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
258   PetscValidType(mat,1);
259 
260   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
261   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
262      In keeping with this convention, we set zerorows to NULL if there are no zero
263      rows. */
264   if (keptrows == NULL) {
265     *zerorows = NULL;
266   } else {
267     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
268     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
269     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
270   }
271   PetscFunctionReturn(0);
272 }
273 
274 /*@
275    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
276 
277    Not Collective
278 
279    Input Parameters:
280 .   A - the matrix
281 
282    Output Parameters:
283 .   a - the diagonal part (which is a SEQUENTIAL matrix)
284 
285    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
286           Use caution, as the reference count on the returned matrix is not incremented and it is used as
287 	  part of the containing MPI Mat's normal operation.
288 
289    Level: advanced
290 
291 @*/
292 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
293 {
294   PetscErrorCode ierr;
295 
296   PetscFunctionBegin;
297   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
298   PetscValidType(A,1);
299   PetscValidPointer(a,3);
300   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
301   if (!A->ops->getdiagonalblock) {
302     PetscMPIInt size;
303     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
304     if (size == 1) {
305       *a = A;
306       PetscFunctionReturn(0);
307     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
308   }
309   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
310   PetscFunctionReturn(0);
311 }
312 
313 /*@
314    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
315 
316    Collective on Mat
317 
318    Input Parameters:
319 .  mat - the matrix
320 
321    Output Parameter:
322 .   trace - the sum of the diagonal entries
323 
324    Level: advanced
325 
326 @*/
327 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
328 {
329   PetscErrorCode ierr;
330   Vec            diag;
331 
332   PetscFunctionBegin;
333   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
334   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
335   ierr = VecSum(diag,trace);CHKERRQ(ierr);
336   ierr = VecDestroy(&diag);CHKERRQ(ierr);
337   PetscFunctionReturn(0);
338 }
339 
340 /*@
341    MatRealPart - Zeros out the imaginary part of the matrix
342 
343    Logically Collective on Mat
344 
345    Input Parameters:
346 .  mat - the matrix
347 
348    Level: advanced
349 
350 
351 .seealso: MatImaginaryPart()
352 @*/
353 PetscErrorCode MatRealPart(Mat mat)
354 {
355   PetscErrorCode ierr;
356 
357   PetscFunctionBegin;
358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
359   PetscValidType(mat,1);
360   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
361   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
362   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
363   MatCheckPreallocated(mat,1);
364   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
365 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
366   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
367     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
368   }
369 #endif
370   PetscFunctionReturn(0);
371 }
372 
373 /*@C
374    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
375 
376    Collective on Mat
377 
378    Input Parameter:
379 .  mat - the matrix
380 
381    Output Parameters:
382 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
383 -   ghosts - the global indices of the ghost points
384 
385    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
386 
387    Level: advanced
388 
389 @*/
390 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
391 {
392   PetscErrorCode ierr;
393 
394   PetscFunctionBegin;
395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
396   PetscValidType(mat,1);
397   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
398   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
399   if (!mat->ops->getghosts) {
400     if (nghosts) *nghosts = 0;
401     if (ghosts) *ghosts = 0;
402   } else {
403     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
404   }
405   PetscFunctionReturn(0);
406 }
407 
408 
409 /*@
410    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
411 
412    Logically Collective on Mat
413 
414    Input Parameters:
415 .  mat - the matrix
416 
417    Level: advanced
418 
419 
420 .seealso: MatRealPart()
421 @*/
422 PetscErrorCode MatImaginaryPart(Mat mat)
423 {
424   PetscErrorCode ierr;
425 
426   PetscFunctionBegin;
427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
428   PetscValidType(mat,1);
429   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
430   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
431   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
432   MatCheckPreallocated(mat,1);
433   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
434 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
435   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
436     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
437   }
438 #endif
439   PetscFunctionReturn(0);
440 }
441 
442 /*@
443    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
444 
445    Not Collective
446 
447    Input Parameter:
448 .  mat - the matrix
449 
450    Output Parameters:
451 +  missing - is any diagonal missing
452 -  dd - first diagonal entry that is missing (optional) on this process
453 
454    Level: advanced
455 
456 
457 .seealso: MatRealPart()
458 @*/
459 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
460 {
461   PetscErrorCode ierr;
462 
463   PetscFunctionBegin;
464   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
465   PetscValidType(mat,1);
466   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
467   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
468   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
469   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
470   PetscFunctionReturn(0);
471 }
472 
473 /*@C
474    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
475    for each row that you get to ensure that your application does
476    not bleed memory.
477 
478    Not Collective
479 
480    Input Parameters:
481 +  mat - the matrix
482 -  row - the row to get
483 
484    Output Parameters:
485 +  ncols -  if not NULL, the number of nonzeros in the row
486 .  cols - if not NULL, the column numbers
487 -  vals - if not NULL, the values
488 
489    Notes:
490    This routine is provided for people who need to have direct access
491    to the structure of a matrix.  We hope that we provide enough
492    high-level matrix routines that few users will need it.
493 
494    MatGetRow() always returns 0-based column indices, regardless of
495    whether the internal representation is 0-based (default) or 1-based.
496 
497    For better efficiency, set cols and/or vals to NULL if you do
498    not wish to extract these quantities.
499 
500    The user can only examine the values extracted with MatGetRow();
501    the values cannot be altered.  To change the matrix entries, one
502    must use MatSetValues().
503 
504    You can only have one call to MatGetRow() outstanding for a particular
505    matrix at a time, per processor. MatGetRow() can only obtain rows
506    associated with the given processor, it cannot get rows from the
507    other processors; for that we suggest using MatCreateSubMatrices(), then
508    MatGetRow() on the submatrix. The row index passed to MatGetRows()
509    is in the global number of rows.
510 
511    Fortran Notes:
512    The calling sequence from Fortran is
513 .vb
514    MatGetRow(matrix,row,ncols,cols,values,ierr)
515          Mat     matrix (input)
516          integer row    (input)
517          integer ncols  (output)
518          integer cols(maxcols) (output)
519          double precision (or double complex) values(maxcols) output
520 .ve
521    where maxcols >= maximum nonzeros in any row of the matrix.
522 
523 
524    Caution:
525    Do not try to change the contents of the output arrays (cols and vals).
526    In some cases, this may corrupt the matrix.
527 
528    Level: advanced
529 
530    Concepts: matrices^row access
531 
532 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
533 @*/
534 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
535 {
536   PetscErrorCode ierr;
537   PetscInt       incols;
538 
539   PetscFunctionBegin;
540   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
541   PetscValidType(mat,1);
542   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
543   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
544   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
545   MatCheckPreallocated(mat,1);
546   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
547   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
548   if (ncols) *ncols = incols;
549   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
550   PetscFunctionReturn(0);
551 }
552 
553 /*@
554    MatConjugate - replaces the matrix values with their complex conjugates
555 
556    Logically Collective on Mat
557 
558    Input Parameters:
559 .  mat - the matrix
560 
561    Level: advanced
562 
563 .seealso:  VecConjugate()
564 @*/
565 PetscErrorCode MatConjugate(Mat mat)
566 {
567 #if defined(PETSC_USE_COMPLEX)
568   PetscErrorCode ierr;
569 
570   PetscFunctionBegin;
571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
572   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
573   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
574   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
575 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
576   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
577     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
578   }
579 #endif
580   PetscFunctionReturn(0);
581 #else
582   return 0;
583 #endif
584 }
585 
586 /*@C
587    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
588 
589    Not Collective
590 
591    Input Parameters:
592 +  mat - the matrix
593 .  row - the row to get
594 .  ncols, cols - the number of nonzeros and their columns
595 -  vals - if nonzero the column values
596 
597    Notes:
598    This routine should be called after you have finished examining the entries.
599 
600    This routine zeros out ncols, cols, and vals. This is to prevent accidental
601    us of the array after it has been restored. If you pass NULL, it will
602    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
603 
604    Fortran Notes:
605    The calling sequence from Fortran is
606 .vb
607    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
608       Mat     matrix (input)
609       integer row    (input)
610       integer ncols  (output)
611       integer cols(maxcols) (output)
612       double precision (or double complex) values(maxcols) output
613 .ve
614    Where maxcols >= maximum nonzeros in any row of the matrix.
615 
616    In Fortran MatRestoreRow() MUST be called after MatGetRow()
617    before another call to MatGetRow() can be made.
618 
619    Level: advanced
620 
621 .seealso:  MatGetRow()
622 @*/
623 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
624 {
625   PetscErrorCode ierr;
626 
627   PetscFunctionBegin;
628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
629   if (ncols) PetscValidIntPointer(ncols,3);
630   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
631   if (!mat->ops->restorerow) PetscFunctionReturn(0);
632   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
633   if (ncols) *ncols = 0;
634   if (cols)  *cols = NULL;
635   if (vals)  *vals = NULL;
636   PetscFunctionReturn(0);
637 }
638 
639 /*@
640    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
641    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
642 
643    Not Collective
644 
645    Input Parameters:
646 +  mat - the matrix
647 
648    Notes:
649    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
650 
651    Level: advanced
652 
653    Concepts: matrices^row access
654 
655 .seealso: MatRestoreRowRowUpperTriangular()
656 @*/
657 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
658 {
659   PetscErrorCode ierr;
660 
661   PetscFunctionBegin;
662   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
663   PetscValidType(mat,1);
664   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
665   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
666   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
667   MatCheckPreallocated(mat,1);
668   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
669   PetscFunctionReturn(0);
670 }
671 
672 /*@
673    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
674 
675    Not Collective
676 
677    Input Parameters:
678 +  mat - the matrix
679 
680    Notes:
681    This routine should be called after you have finished MatGetRow/MatRestoreRow().
682 
683 
684    Level: advanced
685 
686 .seealso:  MatGetRowUpperTriangular()
687 @*/
688 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
689 {
690   PetscErrorCode ierr;
691 
692   PetscFunctionBegin;
693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
694   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
695   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
696   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
697   PetscFunctionReturn(0);
698 }
699 
700 /*@C
701    MatSetOptionsPrefix - Sets the prefix used for searching for all
702    Mat options in the database.
703 
704    Logically Collective on Mat
705 
706    Input Parameter:
707 +  A - the Mat context
708 -  prefix - the prefix to prepend to all option names
709 
710    Notes:
711    A hyphen (-) must NOT be given at the beginning of the prefix name.
712    The first character of all runtime options is AUTOMATICALLY the hyphen.
713 
714    Level: advanced
715 
716 .keywords: Mat, set, options, prefix, database
717 
718 .seealso: MatSetFromOptions()
719 @*/
720 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
721 {
722   PetscErrorCode ierr;
723 
724   PetscFunctionBegin;
725   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
726   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
727   PetscFunctionReturn(0);
728 }
729 
730 /*@C
731    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
732    Mat options in the database.
733 
734    Logically Collective on Mat
735 
736    Input Parameters:
737 +  A - the Mat context
738 -  prefix - the prefix to prepend to all option names
739 
740    Notes:
741    A hyphen (-) must NOT be given at the beginning of the prefix name.
742    The first character of all runtime options is AUTOMATICALLY the hyphen.
743 
744    Level: advanced
745 
746 .keywords: Mat, append, options, prefix, database
747 
748 .seealso: MatGetOptionsPrefix()
749 @*/
750 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
751 {
752   PetscErrorCode ierr;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
756   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 /*@C
761    MatGetOptionsPrefix - Sets the prefix used for searching for all
762    Mat options in the database.
763 
764    Not Collective
765 
766    Input Parameter:
767 .  A - the Mat context
768 
769    Output Parameter:
770 .  prefix - pointer to the prefix string used
771 
772    Notes: On the fortran side, the user should pass in a string 'prefix' of
773    sufficient length to hold the prefix.
774 
775    Level: advanced
776 
777 .keywords: Mat, get, options, prefix, database
778 
779 .seealso: MatAppendOptionsPrefix()
780 @*/
781 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
782 {
783   PetscErrorCode ierr;
784 
785   PetscFunctionBegin;
786   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
787   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
788   PetscFunctionReturn(0);
789 }
790 
791 /*@
792    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
793 
794    Collective on Mat
795 
796    Input Parameters:
797 .  A - the Mat context
798 
799    Notes:
800    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
801    Currently support MPIAIJ and SEQAIJ.
802 
803    Level: beginner
804 
805 .keywords: Mat, ResetPreallocation
806 
807 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
808 @*/
809 PetscErrorCode MatResetPreallocation(Mat A)
810 {
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
815   PetscValidType(A,1);
816   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
817   PetscFunctionReturn(0);
818 }
819 
820 
821 /*@
822    MatSetUp - Sets up the internal matrix data structures for the later use.
823 
824    Collective on Mat
825 
826    Input Parameters:
827 .  A - the Mat context
828 
829    Notes:
830    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
831 
832    If a suitable preallocation routine is used, this function does not need to be called.
833 
834    See the Performance chapter of the PETSc users manual for how to preallocate matrices
835 
836    Level: beginner
837 
838 .keywords: Mat, setup
839 
840 .seealso: MatCreate(), MatDestroy()
841 @*/
842 PetscErrorCode MatSetUp(Mat A)
843 {
844   PetscMPIInt    size;
845   PetscErrorCode ierr;
846 
847   PetscFunctionBegin;
848   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
849   if (!((PetscObject)A)->type_name) {
850     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
851     if (size == 1) {
852       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
853     } else {
854       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
855     }
856   }
857   if (!A->preallocated && A->ops->setup) {
858     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
859     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
860   }
861   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
862   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
863   A->preallocated = PETSC_TRUE;
864   PetscFunctionReturn(0);
865 }
866 
867 #if defined(PETSC_HAVE_SAWS)
868 #include <petscviewersaws.h>
869 #endif
870 /*@C
871    MatView - Visualizes a matrix object.
872 
873    Collective on Mat
874 
875    Input Parameters:
876 +  mat - the matrix
877 -  viewer - visualization context
878 
879   Notes:
880   The available visualization contexts include
881 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
882 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
883 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
884 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
885 
886    The user can open alternative visualization contexts with
887 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
888 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
889          specified file; corresponding input uses MatLoad()
890 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
891          an X window display
892 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
893          Currently only the sequential dense and AIJ
894          matrix types support the Socket viewer.
895 
896    The user can call PetscViewerPushFormat() to specify the output
897    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
898    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
899 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
900 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
901 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
902 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
903          format common among all matrix types
904 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
905          format (which is in many cases the same as the default)
906 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
907          size and structure (not the matrix entries)
908 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
909          the matrix structure
910 
911    Options Database Keys:
912 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
913 .  -mat_view ::ascii_info_detail - Prints more detailed info
914 .  -mat_view - Prints matrix in ASCII format
915 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
916 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
917 .  -display <name> - Sets display name (default is host)
918 .  -draw_pause <sec> - Sets number of seconds to pause after display
919 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
920 .  -viewer_socket_machine <machine> -
921 .  -viewer_socket_port <port> -
922 .  -mat_view binary - save matrix to file in binary format
923 -  -viewer_binary_filename <name> -
924    Level: beginner
925 
926    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
927       viewer is used.
928 
929       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
930       viewer is used.
931 
932       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
933       And then use the following mouse functions:
934           left mouse: zoom in
935           middle mouse: zoom out
936           right mouse: continue with the simulation
937 
938    Concepts: matrices^viewing
939    Concepts: matrices^plotting
940    Concepts: matrices^printing
941 
942 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
943           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
944 @*/
945 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
946 {
947   PetscErrorCode    ierr;
948   PetscInt          rows,cols,rbs,cbs;
949   PetscBool         iascii,ibinary;
950   PetscViewerFormat format;
951   PetscMPIInt       size;
952 #if defined(PETSC_HAVE_SAWS)
953   PetscBool         issaws;
954 #endif
955 
956   PetscFunctionBegin;
957   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
958   PetscValidType(mat,1);
959   if (!viewer) {
960     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
961   }
962   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
963   PetscCheckSameComm(mat,1,viewer,2);
964   MatCheckPreallocated(mat,1);
965   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
966   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
967   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
968   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
969   if (ibinary) {
970     PetscBool mpiio;
971     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
972     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
973   }
974 
975   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
976   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
977   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
978     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
979   }
980 
981 #if defined(PETSC_HAVE_SAWS)
982   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
983 #endif
984   if (iascii) {
985     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
986     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
987     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
988       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
989       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
990       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
991       if (rbs != 1 || cbs != 1) {
992         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
993         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
994       } else {
995         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
996       }
997       if (mat->factortype) {
998         MatSolverType solver;
999         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1000         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1001       }
1002       if (mat->ops->getinfo) {
1003         MatInfo info;
1004         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1005         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1006         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1007       }
1008       if (mat->nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1009       if (mat->nearnullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1010     }
1011 #if defined(PETSC_HAVE_SAWS)
1012   } else if (issaws) {
1013     PetscMPIInt rank;
1014 
1015     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1016     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1017     if (!((PetscObject)mat)->amsmem && !rank) {
1018       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1019     }
1020 #endif
1021   }
1022   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1023     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1024     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1025     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1026   } else if (mat->ops->view) {
1027     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1028     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1029     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1030   }
1031   if (iascii) {
1032     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1033     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1034     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1035       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1036     }
1037   }
1038   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1039   PetscFunctionReturn(0);
1040 }
1041 
1042 #if defined(PETSC_USE_DEBUG)
1043 #include <../src/sys/totalview/tv_data_display.h>
1044 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1045 {
1046   TV_add_row("Local rows", "int", &mat->rmap->n);
1047   TV_add_row("Local columns", "int", &mat->cmap->n);
1048   TV_add_row("Global rows", "int", &mat->rmap->N);
1049   TV_add_row("Global columns", "int", &mat->cmap->N);
1050   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1051   return TV_format_OK;
1052 }
1053 #endif
1054 
1055 /*@C
1056    MatLoad - Loads a matrix that has been stored in binary format
1057    with MatView().  The matrix format is determined from the options database.
1058    Generates a parallel MPI matrix if the communicator has more than one
1059    processor.  The default matrix type is AIJ.
1060 
1061    Collective on PetscViewer
1062 
1063    Input Parameters:
1064 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1065             or some related function before a call to MatLoad()
1066 -  viewer - binary file viewer, created with PetscViewerBinaryOpen()
1067 
1068    Options Database Keys:
1069    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1070    block size
1071 .    -matload_block_size <bs>
1072 
1073    Level: beginner
1074 
1075    Notes:
1076    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1077    Mat before calling this routine if you wish to set it from the options database.
1078 
1079    MatLoad() automatically loads into the options database any options
1080    given in the file filename.info where filename is the name of the file
1081    that was passed to the PetscViewerBinaryOpen(). The options in the info
1082    file will be ignored if you use the -viewer_binary_skip_info option.
1083 
1084    If the type or size of newmat is not set before a call to MatLoad, PETSc
1085    sets the default matrix type AIJ and sets the local and global sizes.
1086    If type and/or size is already set, then the same are used.
1087 
1088    In parallel, each processor can load a subset of rows (or the
1089    entire matrix).  This routine is especially useful when a large
1090    matrix is stored on disk and only part of it is desired on each
1091    processor.  For example, a parallel solver may access only some of
1092    the rows from each processor.  The algorithm used here reads
1093    relatively small blocks of data rather than reading the entire
1094    matrix and then subsetting it.
1095 
1096    Notes for advanced users:
1097    Most users should not need to know the details of the binary storage
1098    format, since MatLoad() and MatView() completely hide these details.
1099    But for anyone who's interested, the standard binary matrix storage
1100    format is
1101 
1102 $    int    MAT_FILE_CLASSID
1103 $    int    number of rows
1104 $    int    number of columns
1105 $    int    total number of nonzeros
1106 $    int    *number nonzeros in each row
1107 $    int    *column indices of all nonzeros (starting index is zero)
1108 $    PetscScalar *values of all nonzeros
1109 
1110    PETSc automatically does the byte swapping for
1111 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1112 linux, Windows and the paragon; thus if you write your own binary
1113 read/write routines you have to swap the bytes; see PetscBinaryRead()
1114 and PetscBinaryWrite() to see how this may be done.
1115 
1116 .keywords: matrix, load, binary, input
1117 
1118 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
1119 
1120  @*/
1121 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1122 {
1123   PetscErrorCode ierr;
1124   PetscBool      isbinary,flg;
1125 
1126   PetscFunctionBegin;
1127   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1128   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1129   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1130   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1131 
1132   if (!((PetscObject)newmat)->type_name) {
1133     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1134   }
1135 
1136   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1137   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1138   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1139   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1140 
1141   flg  = PETSC_FALSE;
1142   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1143   if (flg) {
1144     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1145     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1146   }
1147   flg  = PETSC_FALSE;
1148   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1149   if (flg) {
1150     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1151   }
1152   PetscFunctionReturn(0);
1153 }
1154 
1155 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1156 {
1157   PetscErrorCode ierr;
1158   Mat_Redundant  *redund = *redundant;
1159   PetscInt       i;
1160 
1161   PetscFunctionBegin;
1162   if (redund){
1163     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1164       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1165       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1166       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1167     } else {
1168       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1169       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1170       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1171       for (i=0; i<redund->nrecvs; i++) {
1172         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1173         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1174       }
1175       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1176     }
1177 
1178     if (redund->subcomm) {
1179       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1180     }
1181     ierr = PetscFree(redund);CHKERRQ(ierr);
1182   }
1183   PetscFunctionReturn(0);
1184 }
1185 
1186 /*@
1187    MatDestroy - Frees space taken by a matrix.
1188 
1189    Collective on Mat
1190 
1191    Input Parameter:
1192 .  A - the matrix
1193 
1194    Level: beginner
1195 
1196 @*/
1197 PetscErrorCode MatDestroy(Mat *A)
1198 {
1199   PetscErrorCode ierr;
1200 
1201   PetscFunctionBegin;
1202   if (!*A) PetscFunctionReturn(0);
1203   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1204   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1205 
1206   /* if memory was published with SAWs then destroy it */
1207   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1208   if ((*A)->ops->destroy) {
1209     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1210   }
1211 
1212   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1213   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1214   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1215   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1216   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1217   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1218   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1219   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1220   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1221   PetscFunctionReturn(0);
1222 }
1223 
1224 /*@C
1225    MatSetValues - Inserts or adds a block of values into a matrix.
1226    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1227    MUST be called after all calls to MatSetValues() have been completed.
1228 
1229    Not Collective
1230 
1231    Input Parameters:
1232 +  mat - the matrix
1233 .  v - a logically two-dimensional array of values
1234 .  m, idxm - the number of rows and their global indices
1235 .  n, idxn - the number of columns and their global indices
1236 -  addv - either ADD_VALUES or INSERT_VALUES, where
1237    ADD_VALUES adds values to any existing entries, and
1238    INSERT_VALUES replaces existing entries with new values
1239 
1240    Notes:
1241    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1242       MatSetUp() before using this routine
1243 
1244    By default the values, v, are row-oriented. See MatSetOption() for other options.
1245 
1246    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1247    options cannot be mixed without intervening calls to the assembly
1248    routines.
1249 
1250    MatSetValues() uses 0-based row and column numbers in Fortran
1251    as well as in C.
1252 
1253    Negative indices may be passed in idxm and idxn, these rows and columns are
1254    simply ignored. This allows easily inserting element stiffness matrices
1255    with homogeneous Dirchlet boundary conditions that you don't want represented
1256    in the matrix.
1257 
1258    Efficiency Alert:
1259    The routine MatSetValuesBlocked() may offer much better efficiency
1260    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1261 
1262    Level: beginner
1263 
1264    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
1265                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1266 
1267    Concepts: matrices^putting entries in
1268 
1269 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1270           InsertMode, INSERT_VALUES, ADD_VALUES
1271 @*/
1272 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1273 {
1274   PetscErrorCode ierr;
1275 #if defined(PETSC_USE_DEBUG)
1276   PetscInt       i,j;
1277 #endif
1278 
1279   PetscFunctionBeginHot;
1280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1281   PetscValidType(mat,1);
1282   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1283   PetscValidIntPointer(idxm,3);
1284   PetscValidIntPointer(idxn,5);
1285   PetscValidScalarPointer(v,6);
1286   MatCheckPreallocated(mat,1);
1287   if (mat->insertmode == NOT_SET_VALUES) {
1288     mat->insertmode = addv;
1289   }
1290 #if defined(PETSC_USE_DEBUG)
1291   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1292   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1293   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1294 
1295   for (i=0; i<m; i++) {
1296     for (j=0; j<n; j++) {
1297       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1298 #if defined(PETSC_USE_COMPLEX)
1299         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1300 #else
1301         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1302 #endif
1303     }
1304   }
1305 #endif
1306 
1307   if (mat->assembled) {
1308     mat->was_assembled = PETSC_TRUE;
1309     mat->assembled     = PETSC_FALSE;
1310   }
1311   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1312   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1313   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1314 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1315   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1316     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1317   }
1318 #endif
1319   PetscFunctionReturn(0);
1320 }
1321 
1322 
1323 /*@
1324    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1325         values into a matrix
1326 
1327    Not Collective
1328 
1329    Input Parameters:
1330 +  mat - the matrix
1331 .  row - the (block) row to set
1332 -  v - a logically two-dimensional array of values
1333 
1334    Notes:
1335    By the values, v, are column-oriented (for the block version) and sorted
1336 
1337    All the nonzeros in the row must be provided
1338 
1339    The matrix must have previously had its column indices set
1340 
1341    The row must belong to this process
1342 
1343    Level: intermediate
1344 
1345    Concepts: matrices^putting entries in
1346 
1347 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1348           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1349 @*/
1350 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1351 {
1352   PetscErrorCode ierr;
1353   PetscInt       globalrow;
1354 
1355   PetscFunctionBegin;
1356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1357   PetscValidType(mat,1);
1358   PetscValidScalarPointer(v,2);
1359   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1360   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1361 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1362   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1363     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1364   }
1365 #endif
1366   PetscFunctionReturn(0);
1367 }
1368 
1369 /*@
1370    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1371         values into a matrix
1372 
1373    Not Collective
1374 
1375    Input Parameters:
1376 +  mat - the matrix
1377 .  row - the (block) row to set
1378 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1379 
1380    Notes:
1381    The values, v, are column-oriented for the block version.
1382 
1383    All the nonzeros in the row must be provided
1384 
1385    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1386 
1387    The row must belong to this process
1388 
1389    Level: advanced
1390 
1391    Concepts: matrices^putting entries in
1392 
1393 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1394           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1395 @*/
1396 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1397 {
1398   PetscErrorCode ierr;
1399 
1400   PetscFunctionBeginHot;
1401   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1402   PetscValidType(mat,1);
1403   MatCheckPreallocated(mat,1);
1404   PetscValidScalarPointer(v,2);
1405 #if defined(PETSC_USE_DEBUG)
1406   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1407   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1408 #endif
1409   mat->insertmode = INSERT_VALUES;
1410 
1411   if (mat->assembled) {
1412     mat->was_assembled = PETSC_TRUE;
1413     mat->assembled     = PETSC_FALSE;
1414   }
1415   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1416   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1417   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1418   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1419 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1420   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1421     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1422   }
1423 #endif
1424   PetscFunctionReturn(0);
1425 }
1426 
1427 /*@
1428    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1429      Using structured grid indexing
1430 
1431    Not Collective
1432 
1433    Input Parameters:
1434 +  mat - the matrix
1435 .  m - number of rows being entered
1436 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1437 .  n - number of columns being entered
1438 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1439 .  v - a logically two-dimensional array of values
1440 -  addv - either ADD_VALUES or INSERT_VALUES, where
1441    ADD_VALUES adds values to any existing entries, and
1442    INSERT_VALUES replaces existing entries with new values
1443 
1444    Notes:
1445    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1446 
1447    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1448    options cannot be mixed without intervening calls to the assembly
1449    routines.
1450 
1451    The grid coordinates are across the entire grid, not just the local portion
1452 
1453    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1454    as well as in C.
1455 
1456    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1457 
1458    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1459    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1460 
1461    The columns and rows in the stencil passed in MUST be contained within the
1462    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1463    if you create a DMDA with an overlap of one grid level and on a particular process its first
1464    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1465    first i index you can use in your column and row indices in MatSetStencil() is 5.
1466 
1467    In Fortran idxm and idxn should be declared as
1468 $     MatStencil idxm(4,m),idxn(4,n)
1469    and the values inserted using
1470 $    idxm(MatStencil_i,1) = i
1471 $    idxm(MatStencil_j,1) = j
1472 $    idxm(MatStencil_k,1) = k
1473 $    idxm(MatStencil_c,1) = c
1474    etc
1475 
1476    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1477    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1478    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1479    DM_BOUNDARY_PERIODIC boundary type.
1480 
1481    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1482    a single value per point) you can skip filling those indices.
1483 
1484    Inspired by the structured grid interface to the HYPRE package
1485    (http://www.llnl.gov/CASC/hypre)
1486 
1487    Efficiency Alert:
1488    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1489    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1490 
1491    Level: beginner
1492 
1493    Concepts: matrices^putting entries in
1494 
1495 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1496           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1497 @*/
1498 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1499 {
1500   PetscErrorCode ierr;
1501   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1502   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1503   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1504 
1505   PetscFunctionBegin;
1506   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1507   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1508   PetscValidType(mat,1);
1509   PetscValidIntPointer(idxm,3);
1510   PetscValidIntPointer(idxn,5);
1511   PetscValidScalarPointer(v,6);
1512 
1513   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1514     jdxm = buf; jdxn = buf+m;
1515   } else {
1516     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1517     jdxm = bufm; jdxn = bufn;
1518   }
1519   for (i=0; i<m; i++) {
1520     for (j=0; j<3-sdim; j++) dxm++;
1521     tmp = *dxm++ - starts[0];
1522     for (j=0; j<dim-1; j++) {
1523       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1524       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1525     }
1526     if (mat->stencil.noc) dxm++;
1527     jdxm[i] = tmp;
1528   }
1529   for (i=0; i<n; i++) {
1530     for (j=0; j<3-sdim; j++) dxn++;
1531     tmp = *dxn++ - starts[0];
1532     for (j=0; j<dim-1; j++) {
1533       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1534       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1535     }
1536     if (mat->stencil.noc) dxn++;
1537     jdxn[i] = tmp;
1538   }
1539   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1540   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1541   PetscFunctionReturn(0);
1542 }
1543 
1544 /*@
1545    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1546      Using structured grid indexing
1547 
1548    Not Collective
1549 
1550    Input Parameters:
1551 +  mat - the matrix
1552 .  m - number of rows being entered
1553 .  idxm - grid coordinates for matrix rows being entered
1554 .  n - number of columns being entered
1555 .  idxn - grid coordinates for matrix columns being entered
1556 .  v - a logically two-dimensional array of values
1557 -  addv - either ADD_VALUES or INSERT_VALUES, where
1558    ADD_VALUES adds values to any existing entries, and
1559    INSERT_VALUES replaces existing entries with new values
1560 
1561    Notes:
1562    By default the values, v, are row-oriented and unsorted.
1563    See MatSetOption() for other options.
1564 
1565    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1566    options cannot be mixed without intervening calls to the assembly
1567    routines.
1568 
1569    The grid coordinates are across the entire grid, not just the local portion
1570 
1571    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1572    as well as in C.
1573 
1574    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1575 
1576    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1577    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1578 
1579    The columns and rows in the stencil passed in MUST be contained within the
1580    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1581    if you create a DMDA with an overlap of one grid level and on a particular process its first
1582    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1583    first i index you can use in your column and row indices in MatSetStencil() is 5.
1584 
1585    In Fortran idxm and idxn should be declared as
1586 $     MatStencil idxm(4,m),idxn(4,n)
1587    and the values inserted using
1588 $    idxm(MatStencil_i,1) = i
1589 $    idxm(MatStencil_j,1) = j
1590 $    idxm(MatStencil_k,1) = k
1591    etc
1592 
1593    Negative indices may be passed in idxm and idxn, these rows and columns are
1594    simply ignored. This allows easily inserting element stiffness matrices
1595    with homogeneous Dirchlet boundary conditions that you don't want represented
1596    in the matrix.
1597 
1598    Inspired by the structured grid interface to the HYPRE package
1599    (http://www.llnl.gov/CASC/hypre)
1600 
1601    Level: beginner
1602 
1603    Concepts: matrices^putting entries in
1604 
1605 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1606           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1607           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1608 @*/
1609 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1610 {
1611   PetscErrorCode ierr;
1612   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1613   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1614   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1615 
1616   PetscFunctionBegin;
1617   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1618   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1619   PetscValidType(mat,1);
1620   PetscValidIntPointer(idxm,3);
1621   PetscValidIntPointer(idxn,5);
1622   PetscValidScalarPointer(v,6);
1623 
1624   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1625     jdxm = buf; jdxn = buf+m;
1626   } else {
1627     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1628     jdxm = bufm; jdxn = bufn;
1629   }
1630   for (i=0; i<m; i++) {
1631     for (j=0; j<3-sdim; j++) dxm++;
1632     tmp = *dxm++ - starts[0];
1633     for (j=0; j<sdim-1; j++) {
1634       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1635       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1636     }
1637     dxm++;
1638     jdxm[i] = tmp;
1639   }
1640   for (i=0; i<n; i++) {
1641     for (j=0; j<3-sdim; j++) dxn++;
1642     tmp = *dxn++ - starts[0];
1643     for (j=0; j<sdim-1; j++) {
1644       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1645       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1646     }
1647     dxn++;
1648     jdxn[i] = tmp;
1649   }
1650   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1651   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1652 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1653   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1654     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1655   }
1656 #endif
1657   PetscFunctionReturn(0);
1658 }
1659 
1660 /*@
1661    MatSetStencil - Sets the grid information for setting values into a matrix via
1662         MatSetValuesStencil()
1663 
1664    Not Collective
1665 
1666    Input Parameters:
1667 +  mat - the matrix
1668 .  dim - dimension of the grid 1, 2, or 3
1669 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1670 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1671 -  dof - number of degrees of freedom per node
1672 
1673 
1674    Inspired by the structured grid interface to the HYPRE package
1675    (www.llnl.gov/CASC/hyper)
1676 
1677    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1678    user.
1679 
1680    Level: beginner
1681 
1682    Concepts: matrices^putting entries in
1683 
1684 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1685           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1686 @*/
1687 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1688 {
1689   PetscInt i;
1690 
1691   PetscFunctionBegin;
1692   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1693   PetscValidIntPointer(dims,3);
1694   PetscValidIntPointer(starts,4);
1695 
1696   mat->stencil.dim = dim + (dof > 1);
1697   for (i=0; i<dim; i++) {
1698     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1699     mat->stencil.starts[i] = starts[dim-i-1];
1700   }
1701   mat->stencil.dims[dim]   = dof;
1702   mat->stencil.starts[dim] = 0;
1703   mat->stencil.noc         = (PetscBool)(dof == 1);
1704   PetscFunctionReturn(0);
1705 }
1706 
1707 /*@C
1708    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1709 
1710    Not Collective
1711 
1712    Input Parameters:
1713 +  mat - the matrix
1714 .  v - a logically two-dimensional array of values
1715 .  m, idxm - the number of block rows and their global block indices
1716 .  n, idxn - the number of block columns and their global block indices
1717 -  addv - either ADD_VALUES or INSERT_VALUES, where
1718    ADD_VALUES adds values to any existing entries, and
1719    INSERT_VALUES replaces existing entries with new values
1720 
1721    Notes:
1722    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1723    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1724 
1725    The m and n count the NUMBER of blocks in the row direction and column direction,
1726    NOT the total number of rows/columns; for example, if the block size is 2 and
1727    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1728    The values in idxm would be 1 2; that is the first index for each block divided by
1729    the block size.
1730 
1731    Note that you must call MatSetBlockSize() when constructing this matrix (before
1732    preallocating it).
1733 
1734    By default the values, v, are row-oriented, so the layout of
1735    v is the same as for MatSetValues(). See MatSetOption() for other options.
1736 
1737    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1738    options cannot be mixed without intervening calls to the assembly
1739    routines.
1740 
1741    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1742    as well as in C.
1743 
1744    Negative indices may be passed in idxm and idxn, these rows and columns are
1745    simply ignored. This allows easily inserting element stiffness matrices
1746    with homogeneous Dirchlet boundary conditions that you don't want represented
1747    in the matrix.
1748 
1749    Each time an entry is set within a sparse matrix via MatSetValues(),
1750    internal searching must be done to determine where to place the
1751    data in the matrix storage space.  By instead inserting blocks of
1752    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1753    reduced.
1754 
1755    Example:
1756 $   Suppose m=n=2 and block size(bs) = 2 The array is
1757 $
1758 $   1  2  | 3  4
1759 $   5  6  | 7  8
1760 $   - - - | - - -
1761 $   9  10 | 11 12
1762 $   13 14 | 15 16
1763 $
1764 $   v[] should be passed in like
1765 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1766 $
1767 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1768 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1769 
1770    Level: intermediate
1771 
1772    Concepts: matrices^putting entries in blocked
1773 
1774 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1775 @*/
1776 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1777 {
1778   PetscErrorCode ierr;
1779 
1780   PetscFunctionBeginHot;
1781   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1782   PetscValidType(mat,1);
1783   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1784   PetscValidIntPointer(idxm,3);
1785   PetscValidIntPointer(idxn,5);
1786   PetscValidScalarPointer(v,6);
1787   MatCheckPreallocated(mat,1);
1788   if (mat->insertmode == NOT_SET_VALUES) {
1789     mat->insertmode = addv;
1790   }
1791 #if defined(PETSC_USE_DEBUG)
1792   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1793   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1794   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1795 #endif
1796 
1797   if (mat->assembled) {
1798     mat->was_assembled = PETSC_TRUE;
1799     mat->assembled     = PETSC_FALSE;
1800   }
1801   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1802   if (mat->ops->setvaluesblocked) {
1803     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1804   } else {
1805     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1806     PetscInt i,j,bs,cbs;
1807     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1808     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1809       iidxm = buf; iidxn = buf + m*bs;
1810     } else {
1811       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1812       iidxm = bufr; iidxn = bufc;
1813     }
1814     for (i=0; i<m; i++) {
1815       for (j=0; j<bs; j++) {
1816         iidxm[i*bs+j] = bs*idxm[i] + j;
1817       }
1818     }
1819     for (i=0; i<n; i++) {
1820       for (j=0; j<cbs; j++) {
1821         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1822       }
1823     }
1824     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1825     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1826   }
1827   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1828 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1829   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1830     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1831   }
1832 #endif
1833   PetscFunctionReturn(0);
1834 }
1835 
1836 /*@
1837    MatGetValues - Gets a block of values from a matrix.
1838 
1839    Not Collective; currently only returns a local block
1840 
1841    Input Parameters:
1842 +  mat - the matrix
1843 .  v - a logically two-dimensional array for storing the values
1844 .  m, idxm - the number of rows and their global indices
1845 -  n, idxn - the number of columns and their global indices
1846 
1847    Notes:
1848    The user must allocate space (m*n PetscScalars) for the values, v.
1849    The values, v, are then returned in a row-oriented format,
1850    analogous to that used by default in MatSetValues().
1851 
1852    MatGetValues() uses 0-based row and column numbers in
1853    Fortran as well as in C.
1854 
1855    MatGetValues() requires that the matrix has been assembled
1856    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1857    MatSetValues() and MatGetValues() CANNOT be made in succession
1858    without intermediate matrix assembly.
1859 
1860    Negative row or column indices will be ignored and those locations in v[] will be
1861    left unchanged.
1862 
1863    Level: advanced
1864 
1865    Concepts: matrices^accessing values
1866 
1867 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1868 @*/
1869 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1870 {
1871   PetscErrorCode ierr;
1872 
1873   PetscFunctionBegin;
1874   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1875   PetscValidType(mat,1);
1876   if (!m || !n) PetscFunctionReturn(0);
1877   PetscValidIntPointer(idxm,3);
1878   PetscValidIntPointer(idxn,5);
1879   PetscValidScalarPointer(v,6);
1880   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1881   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1882   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1883   MatCheckPreallocated(mat,1);
1884 
1885   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1886   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1887   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1888   PetscFunctionReturn(0);
1889 }
1890 
1891 /*@
1892   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1893   the same size. Currently, this can only be called once and creates the given matrix.
1894 
1895   Not Collective
1896 
1897   Input Parameters:
1898 + mat - the matrix
1899 . nb - the number of blocks
1900 . bs - the number of rows (and columns) in each block
1901 . rows - a concatenation of the rows for each block
1902 - v - a concatenation of logically two-dimensional arrays of values
1903 
1904   Notes:
1905   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1906 
1907   Level: advanced
1908 
1909   Concepts: matrices^putting entries in
1910 
1911 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1912           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1913 @*/
1914 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1915 {
1916   PetscErrorCode ierr;
1917 
1918   PetscFunctionBegin;
1919   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1920   PetscValidType(mat,1);
1921   PetscValidScalarPointer(rows,4);
1922   PetscValidScalarPointer(v,5);
1923 #if defined(PETSC_USE_DEBUG)
1924   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1925 #endif
1926 
1927   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1928   if (mat->ops->setvaluesbatch) {
1929     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1930   } else {
1931     PetscInt b;
1932     for (b = 0; b < nb; ++b) {
1933       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1934     }
1935   }
1936   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1937   PetscFunctionReturn(0);
1938 }
1939 
1940 /*@
1941    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1942    the routine MatSetValuesLocal() to allow users to insert matrix entries
1943    using a local (per-processor) numbering.
1944 
1945    Not Collective
1946 
1947    Input Parameters:
1948 +  x - the matrix
1949 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1950 - cmapping - column mapping
1951 
1952    Level: intermediate
1953 
1954    Concepts: matrices^local to global mapping
1955    Concepts: local to global mapping^for matrices
1956 
1957 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1958 @*/
1959 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1960 {
1961   PetscErrorCode ierr;
1962 
1963   PetscFunctionBegin;
1964   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
1965   PetscValidType(x,1);
1966   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
1967   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
1968 
1969   if (x->ops->setlocaltoglobalmapping) {
1970     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
1971   } else {
1972     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
1973     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
1974   }
1975   PetscFunctionReturn(0);
1976 }
1977 
1978 
1979 /*@
1980    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1981 
1982    Not Collective
1983 
1984    Input Parameters:
1985 .  A - the matrix
1986 
1987    Output Parameters:
1988 + rmapping - row mapping
1989 - cmapping - column mapping
1990 
1991    Level: advanced
1992 
1993    Concepts: matrices^local to global mapping
1994    Concepts: local to global mapping^for matrices
1995 
1996 .seealso:  MatSetValuesLocal()
1997 @*/
1998 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1999 {
2000   PetscFunctionBegin;
2001   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2002   PetscValidType(A,1);
2003   if (rmapping) PetscValidPointer(rmapping,2);
2004   if (cmapping) PetscValidPointer(cmapping,3);
2005   if (rmapping) *rmapping = A->rmap->mapping;
2006   if (cmapping) *cmapping = A->cmap->mapping;
2007   PetscFunctionReturn(0);
2008 }
2009 
2010 /*@
2011    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2012 
2013    Not Collective
2014 
2015    Input Parameters:
2016 .  A - the matrix
2017 
2018    Output Parameters:
2019 + rmap - row layout
2020 - cmap - column layout
2021 
2022    Level: advanced
2023 
2024 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2025 @*/
2026 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2027 {
2028   PetscFunctionBegin;
2029   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2030   PetscValidType(A,1);
2031   if (rmap) PetscValidPointer(rmap,2);
2032   if (cmap) PetscValidPointer(cmap,3);
2033   if (rmap) *rmap = A->rmap;
2034   if (cmap) *cmap = A->cmap;
2035   PetscFunctionReturn(0);
2036 }
2037 
2038 /*@C
2039    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2040    using a local ordering of the nodes.
2041 
2042    Not Collective
2043 
2044    Input Parameters:
2045 +  mat - the matrix
2046 .  nrow, irow - number of rows and their local indices
2047 .  ncol, icol - number of columns and their local indices
2048 .  y -  a logically two-dimensional array of values
2049 -  addv - either INSERT_VALUES or ADD_VALUES, where
2050    ADD_VALUES adds values to any existing entries, and
2051    INSERT_VALUES replaces existing entries with new values
2052 
2053    Notes:
2054    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2055       MatSetUp() before using this routine
2056 
2057    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2058 
2059    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2060    options cannot be mixed without intervening calls to the assembly
2061    routines.
2062 
2063    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2064    MUST be called after all calls to MatSetValuesLocal() have been completed.
2065 
2066    Level: intermediate
2067 
2068    Concepts: matrices^putting entries in with local numbering
2069 
2070    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2071                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2072 
2073 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2074            MatSetValueLocal()
2075 @*/
2076 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2077 {
2078   PetscErrorCode ierr;
2079 
2080   PetscFunctionBeginHot;
2081   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2082   PetscValidType(mat,1);
2083   MatCheckPreallocated(mat,1);
2084   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2085   PetscValidIntPointer(irow,3);
2086   PetscValidIntPointer(icol,5);
2087   PetscValidScalarPointer(y,6);
2088   if (mat->insertmode == NOT_SET_VALUES) {
2089     mat->insertmode = addv;
2090   }
2091 #if defined(PETSC_USE_DEBUG)
2092   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2093   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2094   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2095 #endif
2096 
2097   if (mat->assembled) {
2098     mat->was_assembled = PETSC_TRUE;
2099     mat->assembled     = PETSC_FALSE;
2100   }
2101   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2102   if (mat->ops->setvalueslocal) {
2103     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2104   } else {
2105     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2106     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2107       irowm = buf; icolm = buf+nrow;
2108     } else {
2109       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2110       irowm = bufr; icolm = bufc;
2111     }
2112     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2113     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2114     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2115     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2116   }
2117   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2118 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
2119   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2120     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2121   }
2122 #endif
2123   PetscFunctionReturn(0);
2124 }
2125 
2126 /*@C
2127    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2128    using a local ordering of the nodes a block at a time.
2129 
2130    Not Collective
2131 
2132    Input Parameters:
2133 +  x - the matrix
2134 .  nrow, irow - number of rows and their local indices
2135 .  ncol, icol - number of columns and their local indices
2136 .  y -  a logically two-dimensional array of values
2137 -  addv - either INSERT_VALUES or ADD_VALUES, where
2138    ADD_VALUES adds values to any existing entries, and
2139    INSERT_VALUES replaces existing entries with new values
2140 
2141    Notes:
2142    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2143       MatSetUp() before using this routine
2144 
2145    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2146       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2147 
2148    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2149    options cannot be mixed without intervening calls to the assembly
2150    routines.
2151 
2152    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2153    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2154 
2155    Level: intermediate
2156 
2157    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2158                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2159 
2160    Concepts: matrices^putting blocked values in with local numbering
2161 
2162 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2163            MatSetValuesLocal(),  MatSetValuesBlocked()
2164 @*/
2165 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2166 {
2167   PetscErrorCode ierr;
2168 
2169   PetscFunctionBeginHot;
2170   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2171   PetscValidType(mat,1);
2172   MatCheckPreallocated(mat,1);
2173   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2174   PetscValidIntPointer(irow,3);
2175   PetscValidIntPointer(icol,5);
2176   PetscValidScalarPointer(y,6);
2177   if (mat->insertmode == NOT_SET_VALUES) {
2178     mat->insertmode = addv;
2179   }
2180 #if defined(PETSC_USE_DEBUG)
2181   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2182   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2183   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2184 #endif
2185 
2186   if (mat->assembled) {
2187     mat->was_assembled = PETSC_TRUE;
2188     mat->assembled     = PETSC_FALSE;
2189   }
2190   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2191   if (mat->ops->setvaluesblockedlocal) {
2192     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2193   } else {
2194     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2195     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2196       irowm = buf; icolm = buf + nrow;
2197     } else {
2198       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2199       irowm = bufr; icolm = bufc;
2200     }
2201     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2202     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2203     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2204     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2205   }
2206   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2207 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
2208   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2209     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2210   }
2211 #endif
2212   PetscFunctionReturn(0);
2213 }
2214 
2215 /*@
2216    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2217 
2218    Collective on Mat and Vec
2219 
2220    Input Parameters:
2221 +  mat - the matrix
2222 -  x   - the vector to be multiplied
2223 
2224    Output Parameters:
2225 .  y - the result
2226 
2227    Notes:
2228    The vectors x and y cannot be the same.  I.e., one cannot
2229    call MatMult(A,y,y).
2230 
2231    Level: developer
2232 
2233    Concepts: matrix-vector product
2234 
2235 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2236 @*/
2237 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2238 {
2239   PetscErrorCode ierr;
2240 
2241   PetscFunctionBegin;
2242   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2243   PetscValidType(mat,1);
2244   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2245   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2246 
2247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2249   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2250   MatCheckPreallocated(mat,1);
2251 
2252   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2253   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2254   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2255   PetscFunctionReturn(0);
2256 }
2257 
2258 /* --------------------------------------------------------*/
2259 /*@
2260    MatMult - Computes the matrix-vector product, y = Ax.
2261 
2262    Neighbor-wise Collective on Mat and Vec
2263 
2264    Input Parameters:
2265 +  mat - the matrix
2266 -  x   - the vector to be multiplied
2267 
2268    Output Parameters:
2269 .  y - the result
2270 
2271    Notes:
2272    The vectors x and y cannot be the same.  I.e., one cannot
2273    call MatMult(A,y,y).
2274 
2275    Level: beginner
2276 
2277    Concepts: matrix-vector product
2278 
2279 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2280 @*/
2281 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2282 {
2283   PetscErrorCode ierr;
2284 
2285   PetscFunctionBegin;
2286   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2287   PetscValidType(mat,1);
2288   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2289   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2290   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2291   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2292   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2293 #if !defined(PETSC_HAVE_CONSTRAINTS)
2294   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2295   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2296   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2297 #endif
2298   VecLocked(y,3);
2299   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2300   MatCheckPreallocated(mat,1);
2301 
2302   ierr = VecLockPush(x);CHKERRQ(ierr);
2303   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2304   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2305   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2306   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2307   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2308   ierr = VecLockPop(x);CHKERRQ(ierr);
2309   PetscFunctionReturn(0);
2310 }
2311 
2312 /*@
2313    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2314 
2315    Neighbor-wise Collective on Mat and Vec
2316 
2317    Input Parameters:
2318 +  mat - the matrix
2319 -  x   - the vector to be multiplied
2320 
2321    Output Parameters:
2322 .  y - the result
2323 
2324    Notes:
2325    The vectors x and y cannot be the same.  I.e., one cannot
2326    call MatMultTranspose(A,y,y).
2327 
2328    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2329    use MatMultHermitianTranspose()
2330 
2331    Level: beginner
2332 
2333    Concepts: matrix vector product^transpose
2334 
2335 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2336 @*/
2337 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2338 {
2339   PetscErrorCode ierr;
2340 
2341   PetscFunctionBegin;
2342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2343   PetscValidType(mat,1);
2344   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2345   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2346 
2347   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2348   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2349   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2350 #if !defined(PETSC_HAVE_CONSTRAINTS)
2351   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2352   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2353 #endif
2354   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2355   MatCheckPreallocated(mat,1);
2356 
2357   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2358   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2359   ierr = VecLockPush(x);CHKERRQ(ierr);
2360   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2361   ierr = VecLockPop(x);CHKERRQ(ierr);
2362   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2363   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2364   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2365   PetscFunctionReturn(0);
2366 }
2367 
2368 /*@
2369    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2370 
2371    Neighbor-wise Collective on Mat and Vec
2372 
2373    Input Parameters:
2374 +  mat - the matrix
2375 -  x   - the vector to be multilplied
2376 
2377    Output Parameters:
2378 .  y - the result
2379 
2380    Notes:
2381    The vectors x and y cannot be the same.  I.e., one cannot
2382    call MatMultHermitianTranspose(A,y,y).
2383 
2384    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2385 
2386    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2387 
2388    Level: beginner
2389 
2390    Concepts: matrix vector product^transpose
2391 
2392 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2393 @*/
2394 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2395 {
2396   PetscErrorCode ierr;
2397   Vec            w;
2398 
2399   PetscFunctionBegin;
2400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2401   PetscValidType(mat,1);
2402   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2403   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2404 
2405   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2406   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2407   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2408 #if !defined(PETSC_HAVE_CONSTRAINTS)
2409   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2410   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2411 #endif
2412   MatCheckPreallocated(mat,1);
2413 
2414   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2415   if (mat->ops->multhermitiantranspose) {
2416     ierr = VecLockPush(x);CHKERRQ(ierr);
2417     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2418     ierr = VecLockPop(x);CHKERRQ(ierr);
2419   } else {
2420     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2421     ierr = VecCopy(x,w);CHKERRQ(ierr);
2422     ierr = VecConjugate(w);CHKERRQ(ierr);
2423     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2424     ierr = VecDestroy(&w);CHKERRQ(ierr);
2425     ierr = VecConjugate(y);CHKERRQ(ierr);
2426   }
2427   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2428   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2429   PetscFunctionReturn(0);
2430 }
2431 
2432 /*@
2433     MatMultAdd -  Computes v3 = v2 + A * v1.
2434 
2435     Neighbor-wise Collective on Mat and Vec
2436 
2437     Input Parameters:
2438 +   mat - the matrix
2439 -   v1, v2 - the vectors
2440 
2441     Output Parameters:
2442 .   v3 - the result
2443 
2444     Notes:
2445     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2446     call MatMultAdd(A,v1,v2,v1).
2447 
2448     Level: beginner
2449 
2450     Concepts: matrix vector product^addition
2451 
2452 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2453 @*/
2454 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2455 {
2456   PetscErrorCode ierr;
2457 
2458   PetscFunctionBegin;
2459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2460   PetscValidType(mat,1);
2461   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2462   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2463   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2464 
2465   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2466   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2467   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2468   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2469      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2470   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2471   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2472   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2473   MatCheckPreallocated(mat,1);
2474 
2475   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2476   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2477   ierr = VecLockPush(v1);CHKERRQ(ierr);
2478   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2479   ierr = VecLockPop(v1);CHKERRQ(ierr);
2480   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2481   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2482   PetscFunctionReturn(0);
2483 }
2484 
2485 /*@
2486    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2487 
2488    Neighbor-wise Collective on Mat and Vec
2489 
2490    Input Parameters:
2491 +  mat - the matrix
2492 -  v1, v2 - the vectors
2493 
2494    Output Parameters:
2495 .  v3 - the result
2496 
2497    Notes:
2498    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2499    call MatMultTransposeAdd(A,v1,v2,v1).
2500 
2501    Level: beginner
2502 
2503    Concepts: matrix vector product^transpose and addition
2504 
2505 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2506 @*/
2507 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2508 {
2509   PetscErrorCode ierr;
2510 
2511   PetscFunctionBegin;
2512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2513   PetscValidType(mat,1);
2514   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2515   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2516   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2517 
2518   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2519   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2520   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2521   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2522   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2523   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2524   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2525   MatCheckPreallocated(mat,1);
2526 
2527   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2528   ierr = VecLockPush(v1);CHKERRQ(ierr);
2529   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2530   ierr = VecLockPop(v1);CHKERRQ(ierr);
2531   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2532   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2533   PetscFunctionReturn(0);
2534 }
2535 
2536 /*@
2537    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2538 
2539    Neighbor-wise Collective on Mat and Vec
2540 
2541    Input Parameters:
2542 +  mat - the matrix
2543 -  v1, v2 - the vectors
2544 
2545    Output Parameters:
2546 .  v3 - the result
2547 
2548    Notes:
2549    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2550    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2551 
2552    Level: beginner
2553 
2554    Concepts: matrix vector product^transpose and addition
2555 
2556 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2557 @*/
2558 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2559 {
2560   PetscErrorCode ierr;
2561 
2562   PetscFunctionBegin;
2563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2564   PetscValidType(mat,1);
2565   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2566   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2567   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2568 
2569   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2570   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2571   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2572   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2573   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2574   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2575   MatCheckPreallocated(mat,1);
2576 
2577   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2578   ierr = VecLockPush(v1);CHKERRQ(ierr);
2579   if (mat->ops->multhermitiantransposeadd) {
2580     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2581    } else {
2582     Vec w,z;
2583     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2584     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2585     ierr = VecConjugate(w);CHKERRQ(ierr);
2586     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2587     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2588     ierr = VecDestroy(&w);CHKERRQ(ierr);
2589     ierr = VecConjugate(z);CHKERRQ(ierr);
2590     ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2591     ierr = VecDestroy(&z);CHKERRQ(ierr);
2592   }
2593   ierr = VecLockPop(v1);CHKERRQ(ierr);
2594   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2595   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2596   PetscFunctionReturn(0);
2597 }
2598 
2599 /*@
2600    MatMultConstrained - The inner multiplication routine for a
2601    constrained matrix P^T A P.
2602 
2603    Neighbor-wise Collective on Mat and Vec
2604 
2605    Input Parameters:
2606 +  mat - the matrix
2607 -  x   - the vector to be multilplied
2608 
2609    Output Parameters:
2610 .  y - the result
2611 
2612    Notes:
2613    The vectors x and y cannot be the same.  I.e., one cannot
2614    call MatMult(A,y,y).
2615 
2616    Level: beginner
2617 
2618 .keywords: matrix, multiply, matrix-vector product, constraint
2619 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2620 @*/
2621 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2622 {
2623   PetscErrorCode ierr;
2624 
2625   PetscFunctionBegin;
2626   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2627   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2628   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2629   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2630   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2631   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2632   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2633   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2634   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2635 
2636   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2637   ierr = VecLockPush(x);CHKERRQ(ierr);
2638   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2639   ierr = VecLockPop(x);CHKERRQ(ierr);
2640   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2641   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2642   PetscFunctionReturn(0);
2643 }
2644 
2645 /*@
2646    MatMultTransposeConstrained - The inner multiplication routine for a
2647    constrained matrix P^T A^T P.
2648 
2649    Neighbor-wise Collective on Mat and Vec
2650 
2651    Input Parameters:
2652 +  mat - the matrix
2653 -  x   - the vector to be multilplied
2654 
2655    Output Parameters:
2656 .  y - the result
2657 
2658    Notes:
2659    The vectors x and y cannot be the same.  I.e., one cannot
2660    call MatMult(A,y,y).
2661 
2662    Level: beginner
2663 
2664 .keywords: matrix, multiply, matrix-vector product, constraint
2665 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2666 @*/
2667 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2668 {
2669   PetscErrorCode ierr;
2670 
2671   PetscFunctionBegin;
2672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2673   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2674   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2675   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2676   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2677   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2678   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2679   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2680 
2681   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2682   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2683   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2684   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2685   PetscFunctionReturn(0);
2686 }
2687 
2688 /*@C
2689    MatGetFactorType - gets the type of factorization it is
2690 
2691    Note Collective
2692    as the flag
2693 
2694    Input Parameters:
2695 .  mat - the matrix
2696 
2697    Output Parameters:
2698 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2699 
2700     Level: intermediate
2701 
2702 .seealso:    MatFactorType, MatGetFactor()
2703 @*/
2704 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2705 {
2706   PetscFunctionBegin;
2707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2708   PetscValidType(mat,1);
2709   *t = mat->factortype;
2710   PetscFunctionReturn(0);
2711 }
2712 
2713 /* ------------------------------------------------------------*/
2714 /*@C
2715    MatGetInfo - Returns information about matrix storage (number of
2716    nonzeros, memory, etc.).
2717 
2718    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2719 
2720    Input Parameters:
2721 .  mat - the matrix
2722 
2723    Output Parameters:
2724 +  flag - flag indicating the type of parameters to be returned
2725    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2726    MAT_GLOBAL_SUM - sum over all processors)
2727 -  info - matrix information context
2728 
2729    Notes:
2730    The MatInfo context contains a variety of matrix data, including
2731    number of nonzeros allocated and used, number of mallocs during
2732    matrix assembly, etc.  Additional information for factored matrices
2733    is provided (such as the fill ratio, number of mallocs during
2734    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2735    when using the runtime options
2736 $       -info -mat_view ::ascii_info
2737 
2738    Example for C/C++ Users:
2739    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2740    data within the MatInfo context.  For example,
2741 .vb
2742       MatInfo info;
2743       Mat     A;
2744       double  mal, nz_a, nz_u;
2745 
2746       MatGetInfo(A,MAT_LOCAL,&info);
2747       mal  = info.mallocs;
2748       nz_a = info.nz_allocated;
2749 .ve
2750 
2751    Example for Fortran Users:
2752    Fortran users should declare info as a double precision
2753    array of dimension MAT_INFO_SIZE, and then extract the parameters
2754    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2755    a complete list of parameter names.
2756 .vb
2757       double  precision info(MAT_INFO_SIZE)
2758       double  precision mal, nz_a
2759       Mat     A
2760       integer ierr
2761 
2762       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2763       mal = info(MAT_INFO_MALLOCS)
2764       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2765 .ve
2766 
2767     Level: intermediate
2768 
2769     Concepts: matrices^getting information on
2770 
2771     Developer Note: fortran interface is not autogenerated as the f90
2772     interface defintion cannot be generated correctly [due to MatInfo]
2773 
2774 .seealso: MatStashGetInfo()
2775 
2776 @*/
2777 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2778 {
2779   PetscErrorCode ierr;
2780 
2781   PetscFunctionBegin;
2782   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2783   PetscValidType(mat,1);
2784   PetscValidPointer(info,3);
2785   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2786   MatCheckPreallocated(mat,1);
2787   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2788   PetscFunctionReturn(0);
2789 }
2790 
2791 /*
2792    This is used by external packages where it is not easy to get the info from the actual
2793    matrix factorization.
2794 */
2795 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2796 {
2797   PetscErrorCode ierr;
2798 
2799   PetscFunctionBegin;
2800   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2801   PetscFunctionReturn(0);
2802 }
2803 
2804 /* ----------------------------------------------------------*/
2805 
2806 /*@C
2807    MatLUFactor - Performs in-place LU factorization of matrix.
2808 
2809    Collective on Mat
2810 
2811    Input Parameters:
2812 +  mat - the matrix
2813 .  row - row permutation
2814 .  col - column permutation
2815 -  info - options for factorization, includes
2816 $          fill - expected fill as ratio of original fill.
2817 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2818 $                   Run with the option -info to determine an optimal value to use
2819 
2820    Notes:
2821    Most users should employ the simplified KSP interface for linear solvers
2822    instead of working directly with matrix algebra routines such as this.
2823    See, e.g., KSPCreate().
2824 
2825    This changes the state of the matrix to a factored matrix; it cannot be used
2826    for example with MatSetValues() unless one first calls MatSetUnfactored().
2827 
2828    Level: developer
2829 
2830    Concepts: matrices^LU factorization
2831 
2832 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2833           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2834 
2835     Developer Note: fortran interface is not autogenerated as the f90
2836     interface defintion cannot be generated correctly [due to MatFactorInfo]
2837 
2838 @*/
2839 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2840 {
2841   PetscErrorCode ierr;
2842   MatFactorInfo  tinfo;
2843 
2844   PetscFunctionBegin;
2845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2846   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2847   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2848   if (info) PetscValidPointer(info,4);
2849   PetscValidType(mat,1);
2850   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2851   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2852   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2853   MatCheckPreallocated(mat,1);
2854   if (!info) {
2855     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2856     info = &tinfo;
2857   }
2858 
2859   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2860   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2861   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2862   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2863   PetscFunctionReturn(0);
2864 }
2865 
2866 /*@C
2867    MatILUFactor - Performs in-place ILU factorization of matrix.
2868 
2869    Collective on Mat
2870 
2871    Input Parameters:
2872 +  mat - the matrix
2873 .  row - row permutation
2874 .  col - column permutation
2875 -  info - structure containing
2876 $      levels - number of levels of fill.
2877 $      expected fill - as ratio of original fill.
2878 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2879                 missing diagonal entries)
2880 
2881    Notes:
2882    Probably really in-place only when level of fill is zero, otherwise allocates
2883    new space to store factored matrix and deletes previous memory.
2884 
2885    Most users should employ the simplified KSP interface for linear solvers
2886    instead of working directly with matrix algebra routines such as this.
2887    See, e.g., KSPCreate().
2888 
2889    Level: developer
2890 
2891    Concepts: matrices^ILU factorization
2892 
2893 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2894 
2895     Developer Note: fortran interface is not autogenerated as the f90
2896     interface defintion cannot be generated correctly [due to MatFactorInfo]
2897 
2898 @*/
2899 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2900 {
2901   PetscErrorCode ierr;
2902 
2903   PetscFunctionBegin;
2904   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2905   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2906   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2907   PetscValidPointer(info,4);
2908   PetscValidType(mat,1);
2909   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2910   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2911   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2912   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2913   MatCheckPreallocated(mat,1);
2914 
2915   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2916   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2917   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2918   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2919   PetscFunctionReturn(0);
2920 }
2921 
2922 /*@C
2923    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2924    Call this routine before calling MatLUFactorNumeric().
2925 
2926    Collective on Mat
2927 
2928    Input Parameters:
2929 +  fact - the factor matrix obtained with MatGetFactor()
2930 .  mat - the matrix
2931 .  row, col - row and column permutations
2932 -  info - options for factorization, includes
2933 $          fill - expected fill as ratio of original fill.
2934 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2935 $                   Run with the option -info to determine an optimal value to use
2936 
2937 
2938    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2939 
2940    Most users should employ the simplified KSP interface for linear solvers
2941    instead of working directly with matrix algebra routines such as this.
2942    See, e.g., KSPCreate().
2943 
2944    Level: developer
2945 
2946    Concepts: matrices^LU symbolic factorization
2947 
2948 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2949 
2950     Developer Note: fortran interface is not autogenerated as the f90
2951     interface defintion cannot be generated correctly [due to MatFactorInfo]
2952 
2953 @*/
2954 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2955 {
2956   PetscErrorCode ierr;
2957 
2958   PetscFunctionBegin;
2959   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2960   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2961   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2962   if (info) PetscValidPointer(info,4);
2963   PetscValidType(mat,1);
2964   PetscValidPointer(fact,5);
2965   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2966   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2967   if (!(fact)->ops->lufactorsymbolic) {
2968     MatSolverType spackage;
2969     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
2970     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2971   }
2972   MatCheckPreallocated(mat,2);
2973 
2974   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2975   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
2976   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2977   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2978   PetscFunctionReturn(0);
2979 }
2980 
2981 /*@C
2982    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2983    Call this routine after first calling MatLUFactorSymbolic().
2984 
2985    Collective on Mat
2986 
2987    Input Parameters:
2988 +  fact - the factor matrix obtained with MatGetFactor()
2989 .  mat - the matrix
2990 -  info - options for factorization
2991 
2992    Notes:
2993    See MatLUFactor() for in-place factorization.  See
2994    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2995 
2996    Most users should employ the simplified KSP interface for linear solvers
2997    instead of working directly with matrix algebra routines such as this.
2998    See, e.g., KSPCreate().
2999 
3000    Level: developer
3001 
3002    Concepts: matrices^LU numeric factorization
3003 
3004 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3005 
3006     Developer Note: fortran interface is not autogenerated as the f90
3007     interface defintion cannot be generated correctly [due to MatFactorInfo]
3008 
3009 @*/
3010 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3011 {
3012   PetscErrorCode ierr;
3013 
3014   PetscFunctionBegin;
3015   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3016   PetscValidType(mat,1);
3017   PetscValidPointer(fact,2);
3018   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3019   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3020   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3021 
3022   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3023   MatCheckPreallocated(mat,2);
3024   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3025   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3026   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3027   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3028   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3029   PetscFunctionReturn(0);
3030 }
3031 
3032 /*@C
3033    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3034    symmetric matrix.
3035 
3036    Collective on Mat
3037 
3038    Input Parameters:
3039 +  mat - the matrix
3040 .  perm - row and column permutations
3041 -  f - expected fill as ratio of original fill
3042 
3043    Notes:
3044    See MatLUFactor() for the nonsymmetric case.  See also
3045    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3046 
3047    Most users should employ the simplified KSP interface for linear solvers
3048    instead of working directly with matrix algebra routines such as this.
3049    See, e.g., KSPCreate().
3050 
3051    Level: developer
3052 
3053    Concepts: matrices^Cholesky factorization
3054 
3055 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3056           MatGetOrdering()
3057 
3058     Developer Note: fortran interface is not autogenerated as the f90
3059     interface defintion cannot be generated correctly [due to MatFactorInfo]
3060 
3061 @*/
3062 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3063 {
3064   PetscErrorCode ierr;
3065 
3066   PetscFunctionBegin;
3067   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3068   PetscValidType(mat,1);
3069   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3070   if (info) PetscValidPointer(info,3);
3071   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3072   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3073   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3074   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3075   MatCheckPreallocated(mat,1);
3076 
3077   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3078   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3079   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3080   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3081   PetscFunctionReturn(0);
3082 }
3083 
3084 /*@C
3085    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3086    of a symmetric matrix.
3087 
3088    Collective on Mat
3089 
3090    Input Parameters:
3091 +  fact - the factor matrix obtained with MatGetFactor()
3092 .  mat - the matrix
3093 .  perm - row and column permutations
3094 -  info - options for factorization, includes
3095 $          fill - expected fill as ratio of original fill.
3096 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3097 $                   Run with the option -info to determine an optimal value to use
3098 
3099    Notes:
3100    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3101    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3102 
3103    Most users should employ the simplified KSP interface for linear solvers
3104    instead of working directly with matrix algebra routines such as this.
3105    See, e.g., KSPCreate().
3106 
3107    Level: developer
3108 
3109    Concepts: matrices^Cholesky symbolic factorization
3110 
3111 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3112           MatGetOrdering()
3113 
3114     Developer Note: fortran interface is not autogenerated as the f90
3115     interface defintion cannot be generated correctly [due to MatFactorInfo]
3116 
3117 @*/
3118 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3119 {
3120   PetscErrorCode ierr;
3121 
3122   PetscFunctionBegin;
3123   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3124   PetscValidType(mat,1);
3125   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3126   if (info) PetscValidPointer(info,3);
3127   PetscValidPointer(fact,4);
3128   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3129   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3130   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3131   if (!(fact)->ops->choleskyfactorsymbolic) {
3132     MatSolverType spackage;
3133     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3134     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3135   }
3136   MatCheckPreallocated(mat,2);
3137 
3138   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3139   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3140   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3141   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3142   PetscFunctionReturn(0);
3143 }
3144 
3145 /*@C
3146    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3147    of a symmetric matrix. Call this routine after first calling
3148    MatCholeskyFactorSymbolic().
3149 
3150    Collective on Mat
3151 
3152    Input Parameters:
3153 +  fact - the factor matrix obtained with MatGetFactor()
3154 .  mat - the initial matrix
3155 .  info - options for factorization
3156 -  fact - the symbolic factor of mat
3157 
3158 
3159    Notes:
3160    Most users should employ the simplified KSP interface for linear solvers
3161    instead of working directly with matrix algebra routines such as this.
3162    See, e.g., KSPCreate().
3163 
3164    Level: developer
3165 
3166    Concepts: matrices^Cholesky numeric factorization
3167 
3168 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3169 
3170     Developer Note: fortran interface is not autogenerated as the f90
3171     interface defintion cannot be generated correctly [due to MatFactorInfo]
3172 
3173 @*/
3174 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3175 {
3176   PetscErrorCode ierr;
3177 
3178   PetscFunctionBegin;
3179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3180   PetscValidType(mat,1);
3181   PetscValidPointer(fact,2);
3182   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3183   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3184   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3185   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3186   MatCheckPreallocated(mat,2);
3187 
3188   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3189   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3190   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3191   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3192   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3193   PetscFunctionReturn(0);
3194 }
3195 
3196 /* ----------------------------------------------------------------*/
3197 /*@
3198    MatSolve - Solves A x = b, given a factored matrix.
3199 
3200    Neighbor-wise Collective on Mat and Vec
3201 
3202    Input Parameters:
3203 +  mat - the factored matrix
3204 -  b - the right-hand-side vector
3205 
3206    Output Parameter:
3207 .  x - the result vector
3208 
3209    Notes:
3210    The vectors b and x cannot be the same.  I.e., one cannot
3211    call MatSolve(A,x,x).
3212 
3213    Notes:
3214    Most users should employ the simplified KSP interface for linear solvers
3215    instead of working directly with matrix algebra routines such as this.
3216    See, e.g., KSPCreate().
3217 
3218    Level: developer
3219 
3220    Concepts: matrices^triangular solves
3221 
3222 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3223 @*/
3224 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3225 {
3226   PetscErrorCode ierr;
3227 
3228   PetscFunctionBegin;
3229   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3230   PetscValidType(mat,1);
3231   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3232   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3233   PetscCheckSameComm(mat,1,b,2);
3234   PetscCheckSameComm(mat,1,x,3);
3235   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3236   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3237   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3238   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3239   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3240   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3241   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3242   MatCheckPreallocated(mat,1);
3243 
3244   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3245   if (mat->factorerrortype) {
3246     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3247     ierr = VecSetInf(x);CHKERRQ(ierr);
3248   } else {
3249     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3250   }
3251   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3252   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3253   PetscFunctionReturn(0);
3254 }
3255 
3256 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3257 {
3258   PetscErrorCode ierr;
3259   Vec            b,x;
3260   PetscInt       m,N,i;
3261   PetscScalar    *bb,*xx;
3262   PetscBool      flg;
3263 
3264   PetscFunctionBegin;
3265   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3266   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3267   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3268   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3269 
3270   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3271   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3272   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3273   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3274   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3275   for (i=0; i<N; i++) {
3276     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3277     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3278     if (trans) {
3279       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3280     } else {
3281       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3282     }
3283     ierr = VecResetArray(x);CHKERRQ(ierr);
3284     ierr = VecResetArray(b);CHKERRQ(ierr);
3285   }
3286   ierr = VecDestroy(&b);CHKERRQ(ierr);
3287   ierr = VecDestroy(&x);CHKERRQ(ierr);
3288   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3289   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3290   PetscFunctionReturn(0);
3291 }
3292 
3293 /*@
3294    MatMatSolve - Solves A X = B, given a factored matrix.
3295 
3296    Neighbor-wise Collective on Mat
3297 
3298    Input Parameters:
3299 +  A - the factored matrix
3300 -  B - the right-hand-side matrix  (dense matrix)
3301 
3302    Output Parameter:
3303 .  X - the result matrix (dense matrix)
3304 
3305    Notes:
3306    The matrices b and x cannot be the same.  I.e., one cannot
3307    call MatMatSolve(A,x,x).
3308 
3309    Notes:
3310    Most users should usually employ the simplified KSP interface for linear solvers
3311    instead of working directly with matrix algebra routines such as this.
3312    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3313    at a time.
3314 
3315    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3316    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3317 
3318    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3319 
3320    Level: developer
3321 
3322    Concepts: matrices^triangular solves
3323 
3324 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3325 @*/
3326 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3327 {
3328   PetscErrorCode ierr;
3329 
3330   PetscFunctionBegin;
3331   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3332   PetscValidType(A,1);
3333   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3334   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3335   PetscCheckSameComm(A,1,B,2);
3336   PetscCheckSameComm(A,1,X,3);
3337   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3338   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3339   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3340   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3341   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3342   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3343   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3344   MatCheckPreallocated(A,1);
3345 
3346   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3347   if (!A->ops->matsolve) {
3348     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3349     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3350   } else {
3351     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3352   }
3353   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3354   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3355   PetscFunctionReturn(0);
3356 }
3357 
3358 /*@
3359    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3360 
3361    Neighbor-wise Collective on Mat
3362 
3363    Input Parameters:
3364 +  A - the factored matrix
3365 -  B - the right-hand-side matrix  (dense matrix)
3366 
3367    Output Parameter:
3368 .  X - the result matrix (dense matrix)
3369 
3370    Notes:
3371    The matrices b and x cannot be the same.  I.e., one cannot
3372    call MatMatSolveTranspose(A,x,x).
3373 
3374    Notes:
3375    Most users should usually employ the simplified KSP interface for linear solvers
3376    instead of working directly with matrix algebra routines such as this.
3377    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3378    at a time.
3379 
3380    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3381    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3382 
3383    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3384 
3385    Level: developer
3386 
3387    Concepts: matrices^triangular solves
3388 
3389 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3390 @*/
3391 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3392 {
3393   PetscErrorCode ierr;
3394 
3395   PetscFunctionBegin;
3396   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3397   PetscValidType(A,1);
3398   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3399   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3400   PetscCheckSameComm(A,1,B,2);
3401   PetscCheckSameComm(A,1,X,3);
3402   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3403   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3404   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3405   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3406   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3407   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3408   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3409   MatCheckPreallocated(A,1);
3410 
3411   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3412   if (!A->ops->matsolvetranspose) {
3413     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3414     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3415   } else {
3416     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3417   }
3418   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3419   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3420   PetscFunctionReturn(0);
3421 }
3422 
3423 /*@
3424    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3425                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3426 
3427    Neighbor-wise Collective on Mat and Vec
3428 
3429    Input Parameters:
3430 +  mat - the factored matrix
3431 -  b - the right-hand-side vector
3432 
3433    Output Parameter:
3434 .  x - the result vector
3435 
3436    Notes:
3437    MatSolve() should be used for most applications, as it performs
3438    a forward solve followed by a backward solve.
3439 
3440    The vectors b and x cannot be the same,  i.e., one cannot
3441    call MatForwardSolve(A,x,x).
3442 
3443    For matrix in seqsbaij format with block size larger than 1,
3444    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3445    MatForwardSolve() solves U^T*D y = b, and
3446    MatBackwardSolve() solves U x = y.
3447    Thus they do not provide a symmetric preconditioner.
3448 
3449    Most users should employ the simplified KSP interface for linear solvers
3450    instead of working directly with matrix algebra routines such as this.
3451    See, e.g., KSPCreate().
3452 
3453    Level: developer
3454 
3455    Concepts: matrices^forward solves
3456 
3457 .seealso: MatSolve(), MatBackwardSolve()
3458 @*/
3459 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3460 {
3461   PetscErrorCode ierr;
3462 
3463   PetscFunctionBegin;
3464   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3465   PetscValidType(mat,1);
3466   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3467   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3468   PetscCheckSameComm(mat,1,b,2);
3469   PetscCheckSameComm(mat,1,x,3);
3470   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3471   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3472   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3473   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3474   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3475   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3476   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3477   MatCheckPreallocated(mat,1);
3478   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3479   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3480   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3481   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3482   PetscFunctionReturn(0);
3483 }
3484 
3485 /*@
3486    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3487                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3488 
3489    Neighbor-wise Collective on Mat and Vec
3490 
3491    Input Parameters:
3492 +  mat - the factored matrix
3493 -  b - the right-hand-side vector
3494 
3495    Output Parameter:
3496 .  x - the result vector
3497 
3498    Notes:
3499    MatSolve() should be used for most applications, as it performs
3500    a forward solve followed by a backward solve.
3501 
3502    The vectors b and x cannot be the same.  I.e., one cannot
3503    call MatBackwardSolve(A,x,x).
3504 
3505    For matrix in seqsbaij format with block size larger than 1,
3506    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3507    MatForwardSolve() solves U^T*D y = b, and
3508    MatBackwardSolve() solves U x = y.
3509    Thus they do not provide a symmetric preconditioner.
3510 
3511    Most users should employ the simplified KSP interface for linear solvers
3512    instead of working directly with matrix algebra routines such as this.
3513    See, e.g., KSPCreate().
3514 
3515    Level: developer
3516 
3517    Concepts: matrices^backward solves
3518 
3519 .seealso: MatSolve(), MatForwardSolve()
3520 @*/
3521 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3522 {
3523   PetscErrorCode ierr;
3524 
3525   PetscFunctionBegin;
3526   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3527   PetscValidType(mat,1);
3528   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3529   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3530   PetscCheckSameComm(mat,1,b,2);
3531   PetscCheckSameComm(mat,1,x,3);
3532   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3533   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3534   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3535   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3536   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3537   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3538   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3539   MatCheckPreallocated(mat,1);
3540 
3541   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3542   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3543   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3544   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3545   PetscFunctionReturn(0);
3546 }
3547 
3548 /*@
3549    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3550 
3551    Neighbor-wise Collective on Mat and Vec
3552 
3553    Input Parameters:
3554 +  mat - the factored matrix
3555 .  b - the right-hand-side vector
3556 -  y - the vector to be added to
3557 
3558    Output Parameter:
3559 .  x - the result vector
3560 
3561    Notes:
3562    The vectors b and x cannot be the same.  I.e., one cannot
3563    call MatSolveAdd(A,x,y,x).
3564 
3565    Most users should employ the simplified KSP interface for linear solvers
3566    instead of working directly with matrix algebra routines such as this.
3567    See, e.g., KSPCreate().
3568 
3569    Level: developer
3570 
3571    Concepts: matrices^triangular solves
3572 
3573 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3574 @*/
3575 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3576 {
3577   PetscScalar    one = 1.0;
3578   Vec            tmp;
3579   PetscErrorCode ierr;
3580 
3581   PetscFunctionBegin;
3582   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3583   PetscValidType(mat,1);
3584   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3585   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3586   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3587   PetscCheckSameComm(mat,1,b,2);
3588   PetscCheckSameComm(mat,1,y,2);
3589   PetscCheckSameComm(mat,1,x,3);
3590   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3591   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3592   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3593   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3594   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3595   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3596   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3597   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3598   MatCheckPreallocated(mat,1);
3599 
3600   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3601   if (mat->ops->solveadd) {
3602     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3603   } else {
3604     /* do the solve then the add manually */
3605     if (x != y) {
3606       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3607       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3608     } else {
3609       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3610       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3611       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3612       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3613       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3614       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3615     }
3616   }
3617   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3618   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3619   PetscFunctionReturn(0);
3620 }
3621 
3622 /*@
3623    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3624 
3625    Neighbor-wise Collective on Mat and Vec
3626 
3627    Input Parameters:
3628 +  mat - the factored matrix
3629 -  b - the right-hand-side vector
3630 
3631    Output Parameter:
3632 .  x - the result vector
3633 
3634    Notes:
3635    The vectors b and x cannot be the same.  I.e., one cannot
3636    call MatSolveTranspose(A,x,x).
3637 
3638    Most users should employ the simplified KSP interface for linear solvers
3639    instead of working directly with matrix algebra routines such as this.
3640    See, e.g., KSPCreate().
3641 
3642    Level: developer
3643 
3644    Concepts: matrices^triangular solves
3645 
3646 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3647 @*/
3648 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3649 {
3650   PetscErrorCode ierr;
3651 
3652   PetscFunctionBegin;
3653   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3654   PetscValidType(mat,1);
3655   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3656   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3657   PetscCheckSameComm(mat,1,b,2);
3658   PetscCheckSameComm(mat,1,x,3);
3659   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3660   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3661   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3662   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3663   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3664   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3665   MatCheckPreallocated(mat,1);
3666   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3667   if (mat->factorerrortype) {
3668     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3669     ierr = VecSetInf(x);CHKERRQ(ierr);
3670   } else {
3671     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3672   }
3673   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3674   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3675   PetscFunctionReturn(0);
3676 }
3677 
3678 /*@
3679    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3680                       factored matrix.
3681 
3682    Neighbor-wise Collective on Mat and Vec
3683 
3684    Input Parameters:
3685 +  mat - the factored matrix
3686 .  b - the right-hand-side vector
3687 -  y - the vector to be added to
3688 
3689    Output Parameter:
3690 .  x - the result vector
3691 
3692    Notes:
3693    The vectors b and x cannot be the same.  I.e., one cannot
3694    call MatSolveTransposeAdd(A,x,y,x).
3695 
3696    Most users should employ the simplified KSP interface for linear solvers
3697    instead of working directly with matrix algebra routines such as this.
3698    See, e.g., KSPCreate().
3699 
3700    Level: developer
3701 
3702    Concepts: matrices^triangular solves
3703 
3704 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3705 @*/
3706 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3707 {
3708   PetscScalar    one = 1.0;
3709   PetscErrorCode ierr;
3710   Vec            tmp;
3711 
3712   PetscFunctionBegin;
3713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3714   PetscValidType(mat,1);
3715   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3716   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3717   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3718   PetscCheckSameComm(mat,1,b,2);
3719   PetscCheckSameComm(mat,1,y,3);
3720   PetscCheckSameComm(mat,1,x,4);
3721   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3722   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3723   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3724   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3725   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3726   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3727   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3728   MatCheckPreallocated(mat,1);
3729 
3730   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3731   if (mat->ops->solvetransposeadd) {
3732     if (mat->factorerrortype) {
3733       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3734       ierr = VecSetInf(x);CHKERRQ(ierr);
3735     } else {
3736       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3737     }
3738   } else {
3739     /* do the solve then the add manually */
3740     if (x != y) {
3741       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3742       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3743     } else {
3744       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3745       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3746       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3747       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3748       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3749       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3750     }
3751   }
3752   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3753   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3754   PetscFunctionReturn(0);
3755 }
3756 /* ----------------------------------------------------------------*/
3757 
3758 /*@
3759    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3760 
3761    Neighbor-wise Collective on Mat and Vec
3762 
3763    Input Parameters:
3764 +  mat - the matrix
3765 .  b - the right hand side
3766 .  omega - the relaxation factor
3767 .  flag - flag indicating the type of SOR (see below)
3768 .  shift -  diagonal shift
3769 .  its - the number of iterations
3770 -  lits - the number of local iterations
3771 
3772    Output Parameters:
3773 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3774 
3775    SOR Flags:
3776 .     SOR_FORWARD_SWEEP - forward SOR
3777 .     SOR_BACKWARD_SWEEP - backward SOR
3778 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3779 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3780 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3781 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3782 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3783          upper/lower triangular part of matrix to
3784          vector (with omega)
3785 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3786 
3787    Notes:
3788    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3789    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3790    on each processor.
3791 
3792    Application programmers will not generally use MatSOR() directly,
3793    but instead will employ the KSP/PC interface.
3794 
3795    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3796 
3797    Notes for Advanced Users:
3798    The flags are implemented as bitwise inclusive or operations.
3799    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3800    to specify a zero initial guess for SSOR.
3801 
3802    Most users should employ the simplified KSP interface for linear solvers
3803    instead of working directly with matrix algebra routines such as this.
3804    See, e.g., KSPCreate().
3805 
3806    Vectors x and b CANNOT be the same
3807 
3808    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3809 
3810    Level: developer
3811 
3812    Concepts: matrices^relaxation
3813    Concepts: matrices^SOR
3814    Concepts: matrices^Gauss-Seidel
3815 
3816 @*/
3817 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3818 {
3819   PetscErrorCode ierr;
3820 
3821   PetscFunctionBegin;
3822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3823   PetscValidType(mat,1);
3824   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3825   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3826   PetscCheckSameComm(mat,1,b,2);
3827   PetscCheckSameComm(mat,1,x,8);
3828   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3829   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3830   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3831   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3832   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3833   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3834   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3835   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3836   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3837 
3838   MatCheckPreallocated(mat,1);
3839   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3840   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3841   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3842   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3843   PetscFunctionReturn(0);
3844 }
3845 
3846 /*
3847       Default matrix copy routine.
3848 */
3849 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3850 {
3851   PetscErrorCode    ierr;
3852   PetscInt          i,rstart = 0,rend = 0,nz;
3853   const PetscInt    *cwork;
3854   const PetscScalar *vwork;
3855 
3856   PetscFunctionBegin;
3857   if (B->assembled) {
3858     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3859   }
3860   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3861   for (i=rstart; i<rend; i++) {
3862     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3863     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3864     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3865   }
3866   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3867   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3868   PetscFunctionReturn(0);
3869 }
3870 
3871 /*@
3872    MatCopy - Copys a matrix to another matrix.
3873 
3874    Collective on Mat
3875 
3876    Input Parameters:
3877 +  A - the matrix
3878 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3879 
3880    Output Parameter:
3881 .  B - where the copy is put
3882 
3883    Notes:
3884    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3885    same nonzero pattern or the routine will crash.
3886 
3887    MatCopy() copies the matrix entries of a matrix to another existing
3888    matrix (after first zeroing the second matrix).  A related routine is
3889    MatConvert(), which first creates a new matrix and then copies the data.
3890 
3891    Level: intermediate
3892 
3893    Concepts: matrices^copying
3894 
3895 .seealso: MatConvert(), MatDuplicate()
3896 
3897 @*/
3898 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3899 {
3900   PetscErrorCode ierr;
3901   PetscInt       i;
3902 
3903   PetscFunctionBegin;
3904   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3905   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3906   PetscValidType(A,1);
3907   PetscValidType(B,2);
3908   PetscCheckSameComm(A,1,B,2);
3909   MatCheckPreallocated(B,2);
3910   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3911   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3912   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3913   MatCheckPreallocated(A,1);
3914   if (A == B) PetscFunctionReturn(0);
3915 
3916   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3917   if (A->ops->copy) {
3918     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3919   } else { /* generic conversion */
3920     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3921   }
3922 
3923   B->stencil.dim = A->stencil.dim;
3924   B->stencil.noc = A->stencil.noc;
3925   for (i=0; i<=A->stencil.dim; i++) {
3926     B->stencil.dims[i]   = A->stencil.dims[i];
3927     B->stencil.starts[i] = A->stencil.starts[i];
3928   }
3929 
3930   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3931   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3932   PetscFunctionReturn(0);
3933 }
3934 
3935 /*@C
3936    MatConvert - Converts a matrix to another matrix, either of the same
3937    or different type.
3938 
3939    Collective on Mat
3940 
3941    Input Parameters:
3942 +  mat - the matrix
3943 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3944    same type as the original matrix.
3945 -  reuse - denotes if the destination matrix is to be created or reused.
3946    Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
3947    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).
3948 
3949    Output Parameter:
3950 .  M - pointer to place new matrix
3951 
3952    Notes:
3953    MatConvert() first creates a new matrix and then copies the data from
3954    the first matrix.  A related routine is MatCopy(), which copies the matrix
3955    entries of one matrix to another already existing matrix context.
3956 
3957    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3958    the MPI communicator of the generated matrix is always the same as the communicator
3959    of the input matrix.
3960 
3961    Level: intermediate
3962 
3963    Concepts: matrices^converting between storage formats
3964 
3965 .seealso: MatCopy(), MatDuplicate()
3966 @*/
3967 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3968 {
3969   PetscErrorCode ierr;
3970   PetscBool      sametype,issame,flg;
3971   char           convname[256],mtype[256];
3972   Mat            B;
3973 
3974   PetscFunctionBegin;
3975   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3976   PetscValidType(mat,1);
3977   PetscValidPointer(M,3);
3978   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3979   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3980   MatCheckPreallocated(mat,1);
3981 
3982   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3983   if (flg) {
3984     newtype = mtype;
3985   }
3986   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3987   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3988   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3989   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
3990 
3991   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3992 
3993   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3994     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3995   } else {
3996     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3997     const char     *prefix[3] = {"seq","mpi",""};
3998     PetscInt       i;
3999     /*
4000        Order of precedence:
4001        1) See if a specialized converter is known to the current matrix.
4002        2) See if a specialized converter is known to the desired matrix class.
4003        3) See if a good general converter is registered for the desired class
4004           (as of 6/27/03 only MATMPIADJ falls into this category).
4005        4) See if a good general converter is known for the current matrix.
4006        5) Use a really basic converter.
4007     */
4008 
4009     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4010     for (i=0; i<3; i++) {
4011       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4012       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4013       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4014       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4015       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4016       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4017       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4018       if (conv) goto foundconv;
4019     }
4020 
4021     /* 2)  See if a specialized converter is known to the desired matrix class. */
4022     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4023     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4024     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4025     for (i=0; i<3; i++) {
4026       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4027       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4028       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4029       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4030       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4031       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4032       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4033       if (conv) {
4034         ierr = MatDestroy(&B);CHKERRQ(ierr);
4035         goto foundconv;
4036       }
4037     }
4038 
4039     /* 3) See if a good general converter is registered for the desired class */
4040     conv = B->ops->convertfrom;
4041     ierr = MatDestroy(&B);CHKERRQ(ierr);
4042     if (conv) goto foundconv;
4043 
4044     /* 4) See if a good general converter is known for the current matrix */
4045     if (mat->ops->convert) {
4046       conv = mat->ops->convert;
4047     }
4048     if (conv) goto foundconv;
4049 
4050     /* 5) Use a really basic converter. */
4051     conv = MatConvert_Basic;
4052 
4053 foundconv:
4054     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4055     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4056     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4057       /* the block sizes must be same if the mappings are copied over */
4058       (*M)->rmap->bs = mat->rmap->bs;
4059       (*M)->cmap->bs = mat->cmap->bs;
4060       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4061       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4062       (*M)->rmap->mapping = mat->rmap->mapping;
4063       (*M)->cmap->mapping = mat->cmap->mapping;
4064     }
4065     (*M)->stencil.dim = mat->stencil.dim;
4066     (*M)->stencil.noc = mat->stencil.noc;
4067     for (i=0; i<=mat->stencil.dim; i++) {
4068       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4069       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4070     }
4071     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4072   }
4073   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4074 
4075   /* Copy Mat options */
4076   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4077   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4078   PetscFunctionReturn(0);
4079 }
4080 
4081 /*@C
4082    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4083 
4084    Not Collective
4085 
4086    Input Parameter:
4087 .  mat - the matrix, must be a factored matrix
4088 
4089    Output Parameter:
4090 .   type - the string name of the package (do not free this string)
4091 
4092    Notes:
4093       In Fortran you pass in a empty string and the package name will be copied into it.
4094     (Make sure the string is long enough)
4095 
4096    Level: intermediate
4097 
4098 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4099 @*/
4100 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4101 {
4102   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4103 
4104   PetscFunctionBegin;
4105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4106   PetscValidType(mat,1);
4107   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4108   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4109   if (!conv) {
4110     *type = MATSOLVERPETSC;
4111   } else {
4112     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4113   }
4114   PetscFunctionReturn(0);
4115 }
4116 
4117 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4118 struct _MatSolverTypeForSpecifcType {
4119   MatType                        mtype;
4120   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4121   MatSolverTypeForSpecifcType next;
4122 };
4123 
4124 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4125 struct _MatSolverTypeHolder {
4126   char                           *name;
4127   MatSolverTypeForSpecifcType handlers;
4128   MatSolverTypeHolder         next;
4129 };
4130 
4131 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4132 
4133 /*@C
4134    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4135 
4136    Input Parameters:
4137 +    package - name of the package, for example petsc or superlu
4138 .    mtype - the matrix type that works with this package
4139 .    ftype - the type of factorization supported by the package
4140 -    getfactor - routine that will create the factored matrix ready to be used
4141 
4142     Level: intermediate
4143 
4144 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4145 @*/
4146 PetscErrorCode MatSolverTypeRegister(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4147 {
4148   PetscErrorCode              ierr;
4149   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4150   PetscBool                   flg;
4151   MatSolverTypeForSpecifcType inext,iprev = NULL;
4152 
4153   PetscFunctionBegin;
4154   if (!next) {
4155     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4156     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4157     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4158     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4159     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4160     PetscFunctionReturn(0);
4161   }
4162   while (next) {
4163     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4164     if (flg) {
4165       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4166       inext = next->handlers;
4167       while (inext) {
4168         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4169         if (flg) {
4170           inext->getfactor[(int)ftype-1] = getfactor;
4171           PetscFunctionReturn(0);
4172         }
4173         iprev = inext;
4174         inext = inext->next;
4175       }
4176       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4177       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4178       iprev->next->getfactor[(int)ftype-1] = getfactor;
4179       PetscFunctionReturn(0);
4180     }
4181     prev = next;
4182     next = next->next;
4183   }
4184   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4185   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4186   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4187   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4188   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4189   PetscFunctionReturn(0);
4190 }
4191 
4192 /*@C
4193    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4194 
4195    Input Parameters:
4196 +    package - name of the package, for example petsc or superlu
4197 .    ftype - the type of factorization supported by the package
4198 -    mtype - the matrix type that works with this package
4199 
4200    Output Parameters:
4201 +   foundpackage - PETSC_TRUE if the package was registered
4202 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4203 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4204 
4205     Level: intermediate
4206 
4207 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4208 @*/
4209 PetscErrorCode MatSolverTypeGet(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4210 {
4211   PetscErrorCode                 ierr;
4212   MatSolverTypeHolder         next = MatSolverTypeHolders;
4213   PetscBool                      flg;
4214   MatSolverTypeForSpecifcType inext;
4215 
4216   PetscFunctionBegin;
4217   if (foundpackage) *foundpackage = PETSC_FALSE;
4218   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4219   if (getfactor)    *getfactor    = NULL;
4220 
4221   if (package) {
4222     while (next) {
4223       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4224       if (flg) {
4225         if (foundpackage) *foundpackage = PETSC_TRUE;
4226         inext = next->handlers;
4227         while (inext) {
4228           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4229           if (flg) {
4230             if (foundmtype) *foundmtype = PETSC_TRUE;
4231             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4232             PetscFunctionReturn(0);
4233           }
4234           inext = inext->next;
4235         }
4236       }
4237       next = next->next;
4238     }
4239   } else {
4240     while (next) {
4241       inext = next->handlers;
4242       while (inext) {
4243         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4244         if (flg && inext->getfactor[(int)ftype-1]) {
4245           if (foundpackage) *foundpackage = PETSC_TRUE;
4246           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4247           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4248           PetscFunctionReturn(0);
4249         }
4250         inext = inext->next;
4251       }
4252       next = next->next;
4253     }
4254   }
4255   PetscFunctionReturn(0);
4256 }
4257 
4258 PetscErrorCode MatSolverTypeDestroy(void)
4259 {
4260   PetscErrorCode              ierr;
4261   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4262   MatSolverTypeForSpecifcType inext,iprev;
4263 
4264   PetscFunctionBegin;
4265   while (next) {
4266     ierr = PetscFree(next->name);CHKERRQ(ierr);
4267     inext = next->handlers;
4268     while (inext) {
4269       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4270       iprev = inext;
4271       inext = inext->next;
4272       ierr = PetscFree(iprev);CHKERRQ(ierr);
4273     }
4274     prev = next;
4275     next = next->next;
4276     ierr = PetscFree(prev);CHKERRQ(ierr);
4277   }
4278   MatSolverTypeHolders = NULL;
4279   PetscFunctionReturn(0);
4280 }
4281 
4282 /*@C
4283    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4284 
4285    Collective on Mat
4286 
4287    Input Parameters:
4288 +  mat - the matrix
4289 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4290 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4291 
4292    Output Parameters:
4293 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4294 
4295    Notes:
4296       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4297      such as pastix, superlu, mumps etc.
4298 
4299       PETSc must have been ./configure to use the external solver, using the option --download-package
4300 
4301    Level: intermediate
4302 
4303 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4304 @*/
4305 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4306 {
4307   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4308   PetscBool      foundpackage,foundmtype;
4309 
4310   PetscFunctionBegin;
4311   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4312   PetscValidType(mat,1);
4313 
4314   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4315   MatCheckPreallocated(mat,1);
4316 
4317   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4318   if (!foundpackage) {
4319     if (type) {
4320       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4321     } else {
4322       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4323     }
4324   }
4325 
4326   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4327   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4328 
4329 #if defined(PETSC_USE_COMPLEX)
4330   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4331 #endif
4332 
4333   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4334   PetscFunctionReturn(0);
4335 }
4336 
4337 /*@C
4338    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4339 
4340    Not Collective
4341 
4342    Input Parameters:
4343 +  mat - the matrix
4344 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4345 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4346 
4347    Output Parameter:
4348 .    flg - PETSC_TRUE if the factorization is available
4349 
4350    Notes:
4351       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4352      such as pastix, superlu, mumps etc.
4353 
4354       PETSc must have been ./configure to use the external solver, using the option --download-package
4355 
4356    Level: intermediate
4357 
4358 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4359 @*/
4360 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4361 {
4362   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4363 
4364   PetscFunctionBegin;
4365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4366   PetscValidType(mat,1);
4367 
4368   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4369   MatCheckPreallocated(mat,1);
4370 
4371   *flg = PETSC_FALSE;
4372   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4373   if (gconv) {
4374     *flg = PETSC_TRUE;
4375   }
4376   PetscFunctionReturn(0);
4377 }
4378 
4379 #include <petscdmtypes.h>
4380 
4381 /*@
4382    MatDuplicate - Duplicates a matrix including the non-zero structure.
4383 
4384    Collective on Mat
4385 
4386    Input Parameters:
4387 +  mat - the matrix
4388 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4389         See the manual page for MatDuplicateOption for an explanation of these options.
4390 
4391    Output Parameter:
4392 .  M - pointer to place new matrix
4393 
4394    Level: intermediate
4395 
4396    Concepts: matrices^duplicating
4397 
4398    Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4399 
4400 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4401 @*/
4402 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4403 {
4404   PetscErrorCode ierr;
4405   Mat            B;
4406   PetscInt       i;
4407   DM             dm;
4408   void           (*viewf)(void);
4409 
4410   PetscFunctionBegin;
4411   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4412   PetscValidType(mat,1);
4413   PetscValidPointer(M,3);
4414   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4415   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4416   MatCheckPreallocated(mat,1);
4417 
4418   *M = 0;
4419   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4420   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4421   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4422   B    = *M;
4423 
4424   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4425   ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4426 
4427   B->stencil.dim = mat->stencil.dim;
4428   B->stencil.noc = mat->stencil.noc;
4429   for (i=0; i<=mat->stencil.dim; i++) {
4430     B->stencil.dims[i]   = mat->stencil.dims[i];
4431     B->stencil.starts[i] = mat->stencil.starts[i];
4432   }
4433 
4434   B->nooffproczerorows = mat->nooffproczerorows;
4435   B->nooffprocentries  = mat->nooffprocentries;
4436 
4437   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4438   if (dm) {
4439     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4440   }
4441   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4442   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4443   PetscFunctionReturn(0);
4444 }
4445 
4446 /*@
4447    MatGetDiagonal - Gets the diagonal of a matrix.
4448 
4449    Logically Collective on Mat and Vec
4450 
4451    Input Parameters:
4452 +  mat - the matrix
4453 -  v - the vector for storing the diagonal
4454 
4455    Output Parameter:
4456 .  v - the diagonal of the matrix
4457 
4458    Level: intermediate
4459 
4460    Note:
4461    Currently only correct in parallel for square matrices.
4462 
4463    Concepts: matrices^accessing diagonals
4464 
4465 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4466 @*/
4467 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4468 {
4469   PetscErrorCode ierr;
4470 
4471   PetscFunctionBegin;
4472   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4473   PetscValidType(mat,1);
4474   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4475   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4476   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4477   MatCheckPreallocated(mat,1);
4478 
4479   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4480   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4481   PetscFunctionReturn(0);
4482 }
4483 
4484 /*@C
4485    MatGetRowMin - Gets the minimum value (of the real part) of each
4486         row of the matrix
4487 
4488    Logically Collective on Mat and Vec
4489 
4490    Input Parameters:
4491 .  mat - the matrix
4492 
4493    Output Parameter:
4494 +  v - the vector for storing the maximums
4495 -  idx - the indices of the column found for each row (optional)
4496 
4497    Level: intermediate
4498 
4499    Notes: The result of this call are the same as if one converted the matrix to dense format
4500       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4501 
4502     This code is only implemented for a couple of matrix formats.
4503 
4504    Concepts: matrices^getting row maximums
4505 
4506 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4507           MatGetRowMax()
4508 @*/
4509 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4510 {
4511   PetscErrorCode ierr;
4512 
4513   PetscFunctionBegin;
4514   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4515   PetscValidType(mat,1);
4516   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4517   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4518   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4519   MatCheckPreallocated(mat,1);
4520 
4521   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4522   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4523   PetscFunctionReturn(0);
4524 }
4525 
4526 /*@C
4527    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4528         row of the matrix
4529 
4530    Logically Collective on Mat and Vec
4531 
4532    Input Parameters:
4533 .  mat - the matrix
4534 
4535    Output Parameter:
4536 +  v - the vector for storing the minimums
4537 -  idx - the indices of the column found for each row (or NULL if not needed)
4538 
4539    Level: intermediate
4540 
4541    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4542     row is 0 (the first column).
4543 
4544     This code is only implemented for a couple of matrix formats.
4545 
4546    Concepts: matrices^getting row maximums
4547 
4548 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4549 @*/
4550 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4551 {
4552   PetscErrorCode ierr;
4553 
4554   PetscFunctionBegin;
4555   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4556   PetscValidType(mat,1);
4557   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4558   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4559   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4560   MatCheckPreallocated(mat,1);
4561   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4562 
4563   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4564   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4565   PetscFunctionReturn(0);
4566 }
4567 
4568 /*@C
4569    MatGetRowMax - Gets the maximum value (of the real part) of each
4570         row of the matrix
4571 
4572    Logically Collective on Mat and Vec
4573 
4574    Input Parameters:
4575 .  mat - the matrix
4576 
4577    Output Parameter:
4578 +  v - the vector for storing the maximums
4579 -  idx - the indices of the column found for each row (optional)
4580 
4581    Level: intermediate
4582 
4583    Notes: The result of this call are the same as if one converted the matrix to dense format
4584       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4585 
4586     This code is only implemented for a couple of matrix formats.
4587 
4588    Concepts: matrices^getting row maximums
4589 
4590 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4591 @*/
4592 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4593 {
4594   PetscErrorCode ierr;
4595 
4596   PetscFunctionBegin;
4597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4598   PetscValidType(mat,1);
4599   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4600   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4601   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4602   MatCheckPreallocated(mat,1);
4603 
4604   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4605   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4606   PetscFunctionReturn(0);
4607 }
4608 
4609 /*@C
4610    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4611         row of the matrix
4612 
4613    Logically Collective on Mat and Vec
4614 
4615    Input Parameters:
4616 .  mat - the matrix
4617 
4618    Output Parameter:
4619 +  v - the vector for storing the maximums
4620 -  idx - the indices of the column found for each row (or NULL if not needed)
4621 
4622    Level: intermediate
4623 
4624    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4625     row is 0 (the first column).
4626 
4627     This code is only implemented for a couple of matrix formats.
4628 
4629    Concepts: matrices^getting row maximums
4630 
4631 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4632 @*/
4633 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4634 {
4635   PetscErrorCode ierr;
4636 
4637   PetscFunctionBegin;
4638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4639   PetscValidType(mat,1);
4640   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4641   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4642   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4643   MatCheckPreallocated(mat,1);
4644   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4645 
4646   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4647   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4648   PetscFunctionReturn(0);
4649 }
4650 
4651 /*@
4652    MatGetRowSum - Gets the sum of each row of the matrix
4653 
4654    Logically or Neighborhood Collective on Mat and Vec
4655 
4656    Input Parameters:
4657 .  mat - the matrix
4658 
4659    Output Parameter:
4660 .  v - the vector for storing the sum of rows
4661 
4662    Level: intermediate
4663 
4664    Notes: This code is slow since it is not currently specialized for different formats
4665 
4666    Concepts: matrices^getting row sums
4667 
4668 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4669 @*/
4670 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4671 {
4672   Vec            ones;
4673   PetscErrorCode ierr;
4674 
4675   PetscFunctionBegin;
4676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4677   PetscValidType(mat,1);
4678   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4679   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4680   MatCheckPreallocated(mat,1);
4681   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4682   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4683   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4684   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4685   PetscFunctionReturn(0);
4686 }
4687 
4688 /*@
4689    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4690 
4691    Collective on Mat
4692 
4693    Input Parameter:
4694 +  mat - the matrix to transpose
4695 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4696 
4697    Output Parameters:
4698 .  B - the transpose
4699 
4700    Notes:
4701      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4702 
4703      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4704 
4705      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4706 
4707    Level: intermediate
4708 
4709    Concepts: matrices^transposing
4710 
4711 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4712 @*/
4713 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4714 {
4715   PetscErrorCode ierr;
4716 
4717   PetscFunctionBegin;
4718   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4719   PetscValidType(mat,1);
4720   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4721   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4722   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4723   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4724   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4725   MatCheckPreallocated(mat,1);
4726 
4727   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4728   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4729   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4730   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4731   PetscFunctionReturn(0);
4732 }
4733 
4734 /*@
4735    MatIsTranspose - Test whether a matrix is another one's transpose,
4736         or its own, in which case it tests symmetry.
4737 
4738    Collective on Mat
4739 
4740    Input Parameter:
4741 +  A - the matrix to test
4742 -  B - the matrix to test against, this can equal the first parameter
4743 
4744    Output Parameters:
4745 .  flg - the result
4746 
4747    Notes:
4748    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4749    has a running time of the order of the number of nonzeros; the parallel
4750    test involves parallel copies of the block-offdiagonal parts of the matrix.
4751 
4752    Level: intermediate
4753 
4754    Concepts: matrices^transposing, matrix^symmetry
4755 
4756 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4757 @*/
4758 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4759 {
4760   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4761 
4762   PetscFunctionBegin;
4763   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4764   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4765   PetscValidPointer(flg,3);
4766   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4767   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4768   *flg = PETSC_FALSE;
4769   if (f && g) {
4770     if (f == g) {
4771       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4772     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4773   } else {
4774     MatType mattype;
4775     if (!f) {
4776       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4777     } else {
4778       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4779     }
4780     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4781   }
4782   PetscFunctionReturn(0);
4783 }
4784 
4785 /*@
4786    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4787 
4788    Collective on Mat
4789 
4790    Input Parameter:
4791 +  mat - the matrix to transpose and complex conjugate
4792 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4793 
4794    Output Parameters:
4795 .  B - the Hermitian
4796 
4797    Level: intermediate
4798 
4799    Concepts: matrices^transposing, complex conjugatex
4800 
4801 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4802 @*/
4803 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4804 {
4805   PetscErrorCode ierr;
4806 
4807   PetscFunctionBegin;
4808   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4809 #if defined(PETSC_USE_COMPLEX)
4810   ierr = MatConjugate(*B);CHKERRQ(ierr);
4811 #endif
4812   PetscFunctionReturn(0);
4813 }
4814 
4815 /*@
4816    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4817 
4818    Collective on Mat
4819 
4820    Input Parameter:
4821 +  A - the matrix to test
4822 -  B - the matrix to test against, this can equal the first parameter
4823 
4824    Output Parameters:
4825 .  flg - the result
4826 
4827    Notes:
4828    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4829    has a running time of the order of the number of nonzeros; the parallel
4830    test involves parallel copies of the block-offdiagonal parts of the matrix.
4831 
4832    Level: intermediate
4833 
4834    Concepts: matrices^transposing, matrix^symmetry
4835 
4836 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4837 @*/
4838 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4839 {
4840   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4841 
4842   PetscFunctionBegin;
4843   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4844   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4845   PetscValidPointer(flg,3);
4846   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4847   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4848   if (f && g) {
4849     if (f==g) {
4850       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4851     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4852   }
4853   PetscFunctionReturn(0);
4854 }
4855 
4856 /*@
4857    MatPermute - Creates a new matrix with rows and columns permuted from the
4858    original.
4859 
4860    Collective on Mat
4861 
4862    Input Parameters:
4863 +  mat - the matrix to permute
4864 .  row - row permutation, each processor supplies only the permutation for its rows
4865 -  col - column permutation, each processor supplies only the permutation for its columns
4866 
4867    Output Parameters:
4868 .  B - the permuted matrix
4869 
4870    Level: advanced
4871 
4872    Note:
4873    The index sets map from row/col of permuted matrix to row/col of original matrix.
4874    The index sets should be on the same communicator as Mat and have the same local sizes.
4875 
4876    Concepts: matrices^permuting
4877 
4878 .seealso: MatGetOrdering(), ISAllGather()
4879 
4880 @*/
4881 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4882 {
4883   PetscErrorCode ierr;
4884 
4885   PetscFunctionBegin;
4886   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4887   PetscValidType(mat,1);
4888   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4889   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4890   PetscValidPointer(B,4);
4891   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4892   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4893   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4894   MatCheckPreallocated(mat,1);
4895 
4896   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4897   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4898   PetscFunctionReturn(0);
4899 }
4900 
4901 /*@
4902    MatEqual - Compares two matrices.
4903 
4904    Collective on Mat
4905 
4906    Input Parameters:
4907 +  A - the first matrix
4908 -  B - the second matrix
4909 
4910    Output Parameter:
4911 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4912 
4913    Level: intermediate
4914 
4915    Concepts: matrices^equality between
4916 @*/
4917 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4918 {
4919   PetscErrorCode ierr;
4920 
4921   PetscFunctionBegin;
4922   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4923   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4924   PetscValidType(A,1);
4925   PetscValidType(B,2);
4926   PetscValidIntPointer(flg,3);
4927   PetscCheckSameComm(A,1,B,2);
4928   MatCheckPreallocated(B,2);
4929   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4930   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4931   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);
4932   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4933   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4934   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);
4935   MatCheckPreallocated(A,1);
4936 
4937   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4938   PetscFunctionReturn(0);
4939 }
4940 
4941 /*@C
4942    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4943    matrices that are stored as vectors.  Either of the two scaling
4944    matrices can be NULL.
4945 
4946    Collective on Mat
4947 
4948    Input Parameters:
4949 +  mat - the matrix to be scaled
4950 .  l - the left scaling vector (or NULL)
4951 -  r - the right scaling vector (or NULL)
4952 
4953    Notes:
4954    MatDiagonalScale() computes A = LAR, where
4955    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4956    The L scales the rows of the matrix, the R scales the columns of the matrix.
4957 
4958    Level: intermediate
4959 
4960    Concepts: matrices^diagonal scaling
4961    Concepts: diagonal scaling of matrices
4962 
4963 .seealso: MatScale(), MatShift(), MatDiagonalSet()
4964 @*/
4965 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4966 {
4967   PetscErrorCode ierr;
4968 
4969   PetscFunctionBegin;
4970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4971   PetscValidType(mat,1);
4972   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4973   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4974   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4975   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4976   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4977   MatCheckPreallocated(mat,1);
4978 
4979   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4980   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4981   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4982   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4983 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
4984   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
4985     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
4986   }
4987 #endif
4988   PetscFunctionReturn(0);
4989 }
4990 
4991 /*@
4992     MatScale - Scales all elements of a matrix by a given number.
4993 
4994     Logically Collective on Mat
4995 
4996     Input Parameters:
4997 +   mat - the matrix to be scaled
4998 -   a  - the scaling value
4999 
5000     Output Parameter:
5001 .   mat - the scaled matrix
5002 
5003     Level: intermediate
5004 
5005     Concepts: matrices^scaling all entries
5006 
5007 .seealso: MatDiagonalScale()
5008 @*/
5009 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5010 {
5011   PetscErrorCode ierr;
5012 
5013   PetscFunctionBegin;
5014   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5015   PetscValidType(mat,1);
5016   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5017   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5018   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5019   PetscValidLogicalCollectiveScalar(mat,a,2);
5020   MatCheckPreallocated(mat,1);
5021 
5022   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5023   if (a != (PetscScalar)1.0) {
5024     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5025     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5026 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5027     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5028       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5029     }
5030 #endif
5031   }
5032   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5033   PetscFunctionReturn(0);
5034 }
5035 
5036 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm)
5037 {
5038   PetscErrorCode ierr;
5039 
5040   PetscFunctionBegin;
5041   if (type == NORM_1 || type == NORM_INFINITY) {
5042     Vec l,r;
5043 
5044     ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr);
5045     if (type == NORM_INFINITY) {
5046       ierr = VecSet(r,1.);CHKERRQ(ierr);
5047       ierr = MatMult(A,r,l);CHKERRQ(ierr);
5048       ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr);
5049     } else {
5050       ierr = VecSet(l,1.);CHKERRQ(ierr);
5051       ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr);
5052       ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr);
5053     }
5054     ierr = VecDestroy(&l);CHKERRQ(ierr);
5055     ierr = VecDestroy(&r);CHKERRQ(ierr);
5056   } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type);
5057   PetscFunctionReturn(0);
5058 }
5059 
5060 /*@
5061    MatNorm - Calculates various norms of a matrix.
5062 
5063    Collective on Mat
5064 
5065    Input Parameters:
5066 +  mat - the matrix
5067 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5068 
5069    Output Parameters:
5070 .  nrm - the resulting norm
5071 
5072    Level: intermediate
5073 
5074    Concepts: matrices^norm
5075    Concepts: norm^of matrix
5076 @*/
5077 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5078 {
5079   PetscErrorCode ierr;
5080 
5081   PetscFunctionBegin;
5082   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5083   PetscValidType(mat,1);
5084   PetscValidLogicalCollectiveEnum(mat,type,2);
5085   PetscValidScalarPointer(nrm,3);
5086 
5087   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5088   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5089   MatCheckPreallocated(mat,1);
5090 
5091   if (!mat->ops->norm) {
5092     ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr);
5093   } else {
5094     ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5095   }
5096   PetscFunctionReturn(0);
5097 }
5098 
5099 /*
5100      This variable is used to prevent counting of MatAssemblyBegin() that
5101    are called from within a MatAssemblyEnd().
5102 */
5103 static PetscInt MatAssemblyEnd_InUse = 0;
5104 /*@
5105    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5106    be called after completing all calls to MatSetValues().
5107 
5108    Collective on Mat
5109 
5110    Input Parameters:
5111 +  mat - the matrix
5112 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5113 
5114    Notes:
5115    MatSetValues() generally caches the values.  The matrix is ready to
5116    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5117    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5118    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5119    using the matrix.
5120 
5121    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5122    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
5123    a global collective operation requring all processes that share the matrix.
5124 
5125    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5126    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5127    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5128 
5129    Level: beginner
5130 
5131    Concepts: matrices^assembling
5132 
5133 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5134 @*/
5135 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5136 {
5137   PetscErrorCode ierr;
5138 
5139   PetscFunctionBegin;
5140   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5141   PetscValidType(mat,1);
5142   MatCheckPreallocated(mat,1);
5143   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5144   if (mat->assembled) {
5145     mat->was_assembled = PETSC_TRUE;
5146     mat->assembled     = PETSC_FALSE;
5147   }
5148   if (!MatAssemblyEnd_InUse) {
5149     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5150     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5151     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5152   } else if (mat->ops->assemblybegin) {
5153     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5154   }
5155   PetscFunctionReturn(0);
5156 }
5157 
5158 /*@
5159    MatAssembled - Indicates if a matrix has been assembled and is ready for
5160      use; for example, in matrix-vector product.
5161 
5162    Not Collective
5163 
5164    Input Parameter:
5165 .  mat - the matrix
5166 
5167    Output Parameter:
5168 .  assembled - PETSC_TRUE or PETSC_FALSE
5169 
5170    Level: advanced
5171 
5172    Concepts: matrices^assembled?
5173 
5174 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5175 @*/
5176 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5177 {
5178   PetscFunctionBegin;
5179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5180   PetscValidType(mat,1);
5181   PetscValidPointer(assembled,2);
5182   *assembled = mat->assembled;
5183   PetscFunctionReturn(0);
5184 }
5185 
5186 /*@
5187    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5188    be called after MatAssemblyBegin().
5189 
5190    Collective on Mat
5191 
5192    Input Parameters:
5193 +  mat - the matrix
5194 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5195 
5196    Options Database Keys:
5197 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5198 .  -mat_view ::ascii_info_detail - Prints more detailed info
5199 .  -mat_view - Prints matrix in ASCII format
5200 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5201 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5202 .  -display <name> - Sets display name (default is host)
5203 .  -draw_pause <sec> - Sets number of seconds to pause after display
5204 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5205 .  -viewer_socket_machine <machine> - Machine to use for socket
5206 .  -viewer_socket_port <port> - Port number to use for socket
5207 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5208 
5209    Notes:
5210    MatSetValues() generally caches the values.  The matrix is ready to
5211    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5212    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5213    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5214    using the matrix.
5215 
5216    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5217    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5218    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5219 
5220    Level: beginner
5221 
5222 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5223 @*/
5224 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5225 {
5226   PetscErrorCode  ierr;
5227   static PetscInt inassm = 0;
5228   PetscBool       flg    = PETSC_FALSE;
5229 
5230   PetscFunctionBegin;
5231   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5232   PetscValidType(mat,1);
5233 
5234   inassm++;
5235   MatAssemblyEnd_InUse++;
5236   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5237     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5238     if (mat->ops->assemblyend) {
5239       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5240     }
5241     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5242   } else if (mat->ops->assemblyend) {
5243     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5244   }
5245 
5246   /* Flush assembly is not a true assembly */
5247   if (type != MAT_FLUSH_ASSEMBLY) {
5248     mat->assembled = PETSC_TRUE; mat->num_ass++;
5249   }
5250   mat->insertmode = NOT_SET_VALUES;
5251   MatAssemblyEnd_InUse--;
5252   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5253   if (!mat->symmetric_eternal) {
5254     mat->symmetric_set              = PETSC_FALSE;
5255     mat->hermitian_set              = PETSC_FALSE;
5256     mat->structurally_symmetric_set = PETSC_FALSE;
5257   }
5258 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5259   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5260     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5261   }
5262 #endif
5263   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5264     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5265 
5266     if (mat->checksymmetryonassembly) {
5267       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5268       if (flg) {
5269         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5270       } else {
5271         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5272       }
5273     }
5274     if (mat->nullsp && mat->checknullspaceonassembly) {
5275       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5276     }
5277   }
5278   inassm--;
5279   PetscFunctionReturn(0);
5280 }
5281 
5282 /*@
5283    MatSetOption - Sets a parameter option for a matrix. Some options
5284    may be specific to certain storage formats.  Some options
5285    determine how values will be inserted (or added). Sorted,
5286    row-oriented input will generally assemble the fastest. The default
5287    is row-oriented.
5288 
5289    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5290 
5291    Input Parameters:
5292 +  mat - the matrix
5293 .  option - the option, one of those listed below (and possibly others),
5294 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5295 
5296   Options Describing Matrix Structure:
5297 +    MAT_SPD - symmetric positive definite
5298 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5299 .    MAT_HERMITIAN - transpose is the complex conjugation
5300 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5301 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5302                             you set to be kept with all future use of the matrix
5303                             including after MatAssemblyBegin/End() which could
5304                             potentially change the symmetry structure, i.e. you
5305                             KNOW the matrix will ALWAYS have the property you set.
5306 
5307 
5308    Options For Use with MatSetValues():
5309    Insert a logically dense subblock, which can be
5310 .    MAT_ROW_ORIENTED - row-oriented (default)
5311 
5312    Note these options reflect the data you pass in with MatSetValues(); it has
5313    nothing to do with how the data is stored internally in the matrix
5314    data structure.
5315 
5316    When (re)assembling a matrix, we can restrict the input for
5317    efficiency/debugging purposes.  These options include:
5318 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5319 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5320 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5321 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5322 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5323 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5324         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5325         performance for very large process counts.
5326 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5327         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5328         functions, instead sending only neighbor messages.
5329 
5330    Notes:
5331    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5332 
5333    Some options are relevant only for particular matrix types and
5334    are thus ignored by others.  Other options are not supported by
5335    certain matrix types and will generate an error message if set.
5336 
5337    If using a Fortran 77 module to compute a matrix, one may need to
5338    use the column-oriented option (or convert to the row-oriented
5339    format).
5340 
5341    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5342    that would generate a new entry in the nonzero structure is instead
5343    ignored.  Thus, if memory has not alredy been allocated for this particular
5344    data, then the insertion is ignored. For dense matrices, in which
5345    the entire array is allocated, no entries are ever ignored.
5346    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5347 
5348    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5349    that would generate a new entry in the nonzero structure instead produces
5350    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
5351 
5352    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5353    that would generate a new entry that has not been preallocated will
5354    instead produce an error. (Currently supported for AIJ and BAIJ formats
5355    only.) This is a useful flag when debugging matrix memory preallocation.
5356    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5357 
5358    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5359    other processors should be dropped, rather than stashed.
5360    This is useful if you know that the "owning" processor is also
5361    always generating the correct matrix entries, so that PETSc need
5362    not transfer duplicate entries generated on another processor.
5363 
5364    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5365    searches during matrix assembly. When this flag is set, the hash table
5366    is created during the first Matrix Assembly. This hash table is
5367    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5368    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5369    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5370    supported by MATMPIBAIJ format only.
5371 
5372    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5373    are kept in the nonzero structure
5374 
5375    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5376    a zero location in the matrix
5377 
5378    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5379 
5380    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5381         zero row routines and thus improves performance for very large process counts.
5382 
5383    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5384         part of the matrix (since they should match the upper triangular part).
5385 
5386    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5387 
5388    Level: intermediate
5389 
5390    Concepts: matrices^setting options
5391 
5392 .seealso:  MatOption, Mat
5393 
5394 @*/
5395 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5396 {
5397   PetscErrorCode ierr;
5398 
5399   PetscFunctionBegin;
5400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5401   PetscValidType(mat,1);
5402   if (op > 0) {
5403     PetscValidLogicalCollectiveEnum(mat,op,2);
5404     PetscValidLogicalCollectiveBool(mat,flg,3);
5405   }
5406 
5407   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);
5408   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()");
5409 
5410   switch (op) {
5411   case MAT_NO_OFF_PROC_ENTRIES:
5412     mat->nooffprocentries = flg;
5413     PetscFunctionReturn(0);
5414     break;
5415   case MAT_SUBSET_OFF_PROC_ENTRIES:
5416     mat->subsetoffprocentries = flg;
5417     PetscFunctionReturn(0);
5418   case MAT_NO_OFF_PROC_ZERO_ROWS:
5419     mat->nooffproczerorows = flg;
5420     PetscFunctionReturn(0);
5421     break;
5422   case MAT_SPD:
5423     mat->spd_set = PETSC_TRUE;
5424     mat->spd     = flg;
5425     if (flg) {
5426       mat->symmetric                  = PETSC_TRUE;
5427       mat->structurally_symmetric     = PETSC_TRUE;
5428       mat->symmetric_set              = PETSC_TRUE;
5429       mat->structurally_symmetric_set = PETSC_TRUE;
5430     }
5431     break;
5432   case MAT_SYMMETRIC:
5433     mat->symmetric = flg;
5434     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5435     mat->symmetric_set              = PETSC_TRUE;
5436     mat->structurally_symmetric_set = flg;
5437 #if !defined(PETSC_USE_COMPLEX)
5438     mat->hermitian     = flg;
5439     mat->hermitian_set = PETSC_TRUE;
5440 #endif
5441     break;
5442   case MAT_HERMITIAN:
5443     mat->hermitian = flg;
5444     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5445     mat->hermitian_set              = PETSC_TRUE;
5446     mat->structurally_symmetric_set = flg;
5447 #if !defined(PETSC_USE_COMPLEX)
5448     mat->symmetric     = flg;
5449     mat->symmetric_set = PETSC_TRUE;
5450 #endif
5451     break;
5452   case MAT_STRUCTURALLY_SYMMETRIC:
5453     mat->structurally_symmetric     = flg;
5454     mat->structurally_symmetric_set = PETSC_TRUE;
5455     break;
5456   case MAT_SYMMETRY_ETERNAL:
5457     mat->symmetric_eternal = flg;
5458     break;
5459   case MAT_STRUCTURE_ONLY:
5460     mat->structure_only = flg;
5461     break;
5462   default:
5463     break;
5464   }
5465   if (mat->ops->setoption) {
5466     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5467   }
5468   PetscFunctionReturn(0);
5469 }
5470 
5471 /*@
5472    MatGetOption - Gets a parameter option that has been set for a matrix.
5473 
5474    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5475 
5476    Input Parameters:
5477 +  mat - the matrix
5478 -  option - the option, this only responds to certain options, check the code for which ones
5479 
5480    Output Parameter:
5481 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5482 
5483     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5484 
5485    Level: intermediate
5486 
5487    Concepts: matrices^setting options
5488 
5489 .seealso:  MatOption, MatSetOption()
5490 
5491 @*/
5492 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5493 {
5494   PetscFunctionBegin;
5495   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5496   PetscValidType(mat,1);
5497 
5498   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);
5499   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()");
5500 
5501   switch (op) {
5502   case MAT_NO_OFF_PROC_ENTRIES:
5503     *flg = mat->nooffprocentries;
5504     break;
5505   case MAT_NO_OFF_PROC_ZERO_ROWS:
5506     *flg = mat->nooffproczerorows;
5507     break;
5508   case MAT_SYMMETRIC:
5509     *flg = mat->symmetric;
5510     break;
5511   case MAT_HERMITIAN:
5512     *flg = mat->hermitian;
5513     break;
5514   case MAT_STRUCTURALLY_SYMMETRIC:
5515     *flg = mat->structurally_symmetric;
5516     break;
5517   case MAT_SYMMETRY_ETERNAL:
5518     *flg = mat->symmetric_eternal;
5519     break;
5520   case MAT_SPD:
5521     *flg = mat->spd;
5522     break;
5523   default:
5524     break;
5525   }
5526   PetscFunctionReturn(0);
5527 }
5528 
5529 /*@
5530    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5531    this routine retains the old nonzero structure.
5532 
5533    Logically Collective on Mat
5534 
5535    Input Parameters:
5536 .  mat - the matrix
5537 
5538    Level: intermediate
5539 
5540    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.
5541    See the Performance chapter of the users manual for information on preallocating matrices.
5542 
5543    Concepts: matrices^zeroing
5544 
5545 .seealso: MatZeroRows()
5546 @*/
5547 PetscErrorCode MatZeroEntries(Mat mat)
5548 {
5549   PetscErrorCode ierr;
5550 
5551   PetscFunctionBegin;
5552   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5553   PetscValidType(mat,1);
5554   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5555   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");
5556   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5557   MatCheckPreallocated(mat,1);
5558 
5559   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5560   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5561   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5562   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5563 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5564   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5565     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5566   }
5567 #endif
5568   PetscFunctionReturn(0);
5569 }
5570 
5571 /*@C
5572    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5573    of a set of rows and columns of a matrix.
5574 
5575    Collective on Mat
5576 
5577    Input Parameters:
5578 +  mat - the matrix
5579 .  numRows - the number of rows to remove
5580 .  rows - the global row indices
5581 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5582 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5583 -  b - optional vector of right hand side, that will be adjusted by provided solution
5584 
5585    Notes:
5586    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5587 
5588    The user can set a value in the diagonal entry (or for the AIJ and
5589    row formats can optionally remove the main diagonal entry from the
5590    nonzero structure as well, by passing 0.0 as the final argument).
5591 
5592    For the parallel case, all processes that share the matrix (i.e.,
5593    those in the communicator used for matrix creation) MUST call this
5594    routine, regardless of whether any rows being zeroed are owned by
5595    them.
5596 
5597    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5598    list only rows local to itself).
5599 
5600    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5601 
5602    Level: intermediate
5603 
5604    Concepts: matrices^zeroing rows
5605 
5606 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5607           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5608 @*/
5609 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5610 {
5611   PetscErrorCode ierr;
5612 
5613   PetscFunctionBegin;
5614   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5615   PetscValidType(mat,1);
5616   if (numRows) PetscValidIntPointer(rows,3);
5617   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5618   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5619   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5620   MatCheckPreallocated(mat,1);
5621 
5622   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5623   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5624   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5625 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5626   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5627     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5628   }
5629 #endif
5630   PetscFunctionReturn(0);
5631 }
5632 
5633 /*@C
5634    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5635    of a set of rows and columns of a matrix.
5636 
5637    Collective on Mat
5638 
5639    Input Parameters:
5640 +  mat - the matrix
5641 .  is - the rows to zero
5642 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5643 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5644 -  b - optional vector of right hand side, that will be adjusted by provided solution
5645 
5646    Notes:
5647    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5648 
5649    The user can set a value in the diagonal entry (or for the AIJ and
5650    row formats can optionally remove the main diagonal entry from the
5651    nonzero structure as well, by passing 0.0 as the final argument).
5652 
5653    For the parallel case, all processes that share the matrix (i.e.,
5654    those in the communicator used for matrix creation) MUST call this
5655    routine, regardless of whether any rows being zeroed are owned by
5656    them.
5657 
5658    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5659    list only rows local to itself).
5660 
5661    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5662 
5663    Level: intermediate
5664 
5665    Concepts: matrices^zeroing rows
5666 
5667 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5668           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5669 @*/
5670 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5671 {
5672   PetscErrorCode ierr;
5673   PetscInt       numRows;
5674   const PetscInt *rows;
5675 
5676   PetscFunctionBegin;
5677   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5678   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5679   PetscValidType(mat,1);
5680   PetscValidType(is,2);
5681   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5682   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5683   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5684   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5685   PetscFunctionReturn(0);
5686 }
5687 
5688 /*@C
5689    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5690    of a set of rows of a matrix.
5691 
5692    Collective on Mat
5693 
5694    Input Parameters:
5695 +  mat - the matrix
5696 .  numRows - the number of rows to remove
5697 .  rows - the global row indices
5698 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5699 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5700 -  b - optional vector of right hand side, that will be adjusted by provided solution
5701 
5702    Notes:
5703    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5704    but does not release memory.  For the dense and block diagonal
5705    formats this does not alter the nonzero structure.
5706 
5707    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5708    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5709    merely zeroed.
5710 
5711    The user can set a value in the diagonal entry (or for the AIJ and
5712    row formats can optionally remove the main diagonal entry from the
5713    nonzero structure as well, by passing 0.0 as the final argument).
5714 
5715    For the parallel case, all processes that share the matrix (i.e.,
5716    those in the communicator used for matrix creation) MUST call this
5717    routine, regardless of whether any rows being zeroed are owned by
5718    them.
5719 
5720    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5721    list only rows local to itself).
5722 
5723    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5724    owns that are to be zeroed. This saves a global synchronization in the implementation.
5725 
5726    Level: intermediate
5727 
5728    Concepts: matrices^zeroing rows
5729 
5730 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5731           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5732 @*/
5733 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5734 {
5735   PetscErrorCode ierr;
5736 
5737   PetscFunctionBegin;
5738   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5739   PetscValidType(mat,1);
5740   if (numRows) PetscValidIntPointer(rows,3);
5741   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5742   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5743   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5744   MatCheckPreallocated(mat,1);
5745 
5746   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5747   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5748   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5749 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5750   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5751     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5752   }
5753 #endif
5754   PetscFunctionReturn(0);
5755 }
5756 
5757 /*@C
5758    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5759    of a set of rows of a matrix.
5760 
5761    Collective on Mat
5762 
5763    Input Parameters:
5764 +  mat - the matrix
5765 .  is - index set of rows to remove
5766 .  diag - value put in all diagonals of eliminated rows
5767 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5768 -  b - optional vector of right hand side, that will be adjusted by provided solution
5769 
5770    Notes:
5771    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5772    but does not release memory.  For the dense and block diagonal
5773    formats this does not alter the nonzero structure.
5774 
5775    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5776    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5777    merely zeroed.
5778 
5779    The user can set a value in the diagonal entry (or for the AIJ and
5780    row formats can optionally remove the main diagonal entry from the
5781    nonzero structure as well, by passing 0.0 as the final argument).
5782 
5783    For the parallel case, all processes that share the matrix (i.e.,
5784    those in the communicator used for matrix creation) MUST call this
5785    routine, regardless of whether any rows being zeroed are owned by
5786    them.
5787 
5788    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5789    list only rows local to itself).
5790 
5791    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5792    owns that are to be zeroed. This saves a global synchronization in the implementation.
5793 
5794    Level: intermediate
5795 
5796    Concepts: matrices^zeroing rows
5797 
5798 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5799           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5800 @*/
5801 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5802 {
5803   PetscInt       numRows;
5804   const PetscInt *rows;
5805   PetscErrorCode ierr;
5806 
5807   PetscFunctionBegin;
5808   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5809   PetscValidType(mat,1);
5810   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5811   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5812   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5813   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5814   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5815   PetscFunctionReturn(0);
5816 }
5817 
5818 /*@C
5819    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5820    of a set of rows of a matrix. These rows must be local to the process.
5821 
5822    Collective on Mat
5823 
5824    Input Parameters:
5825 +  mat - the matrix
5826 .  numRows - the number of rows to remove
5827 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5828 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5829 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5830 -  b - optional vector of right hand side, that will be adjusted by provided solution
5831 
5832    Notes:
5833    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5834    but does not release memory.  For the dense and block diagonal
5835    formats this does not alter the nonzero structure.
5836 
5837    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5838    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5839    merely zeroed.
5840 
5841    The user can set a value in the diagonal entry (or for the AIJ and
5842    row formats can optionally remove the main diagonal entry from the
5843    nonzero structure as well, by passing 0.0 as the final argument).
5844 
5845    For the parallel case, all processes that share the matrix (i.e.,
5846    those in the communicator used for matrix creation) MUST call this
5847    routine, regardless of whether any rows being zeroed are owned by
5848    them.
5849 
5850    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5851    list only rows local to itself).
5852 
5853    The grid coordinates are across the entire grid, not just the local portion
5854 
5855    In Fortran idxm and idxn should be declared as
5856 $     MatStencil idxm(4,m)
5857    and the values inserted using
5858 $    idxm(MatStencil_i,1) = i
5859 $    idxm(MatStencil_j,1) = j
5860 $    idxm(MatStencil_k,1) = k
5861 $    idxm(MatStencil_c,1) = c
5862    etc
5863 
5864    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5865    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5866    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5867    DM_BOUNDARY_PERIODIC boundary type.
5868 
5869    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
5870    a single value per point) you can skip filling those indices.
5871 
5872    Level: intermediate
5873 
5874    Concepts: matrices^zeroing rows
5875 
5876 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5877           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5878 @*/
5879 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5880 {
5881   PetscInt       dim     = mat->stencil.dim;
5882   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5883   PetscInt       *dims   = mat->stencil.dims+1;
5884   PetscInt       *starts = mat->stencil.starts;
5885   PetscInt       *dxm    = (PetscInt*) rows;
5886   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5887   PetscErrorCode ierr;
5888 
5889   PetscFunctionBegin;
5890   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5891   PetscValidType(mat,1);
5892   if (numRows) PetscValidIntPointer(rows,3);
5893 
5894   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5895   for (i = 0; i < numRows; ++i) {
5896     /* Skip unused dimensions (they are ordered k, j, i, c) */
5897     for (j = 0; j < 3-sdim; ++j) dxm++;
5898     /* Local index in X dir */
5899     tmp = *dxm++ - starts[0];
5900     /* Loop over remaining dimensions */
5901     for (j = 0; j < dim-1; ++j) {
5902       /* If nonlocal, set index to be negative */
5903       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5904       /* Update local index */
5905       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5906     }
5907     /* Skip component slot if necessary */
5908     if (mat->stencil.noc) dxm++;
5909     /* Local row number */
5910     if (tmp >= 0) {
5911       jdxm[numNewRows++] = tmp;
5912     }
5913   }
5914   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5915   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5916   PetscFunctionReturn(0);
5917 }
5918 
5919 /*@C
5920    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5921    of a set of rows and columns of a matrix.
5922 
5923    Collective on Mat
5924 
5925    Input Parameters:
5926 +  mat - the matrix
5927 .  numRows - the number of rows/columns to remove
5928 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5929 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5930 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5931 -  b - optional vector of right hand side, that will be adjusted by provided solution
5932 
5933    Notes:
5934    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5935    but does not release memory.  For the dense and block diagonal
5936    formats this does not alter the nonzero structure.
5937 
5938    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5939    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5940    merely zeroed.
5941 
5942    The user can set a value in the diagonal entry (or for the AIJ and
5943    row formats can optionally remove the main diagonal entry from the
5944    nonzero structure as well, by passing 0.0 as the final argument).
5945 
5946    For the parallel case, all processes that share the matrix (i.e.,
5947    those in the communicator used for matrix creation) MUST call this
5948    routine, regardless of whether any rows being zeroed are owned by
5949    them.
5950 
5951    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5952    list only rows local to itself, but the row/column numbers are given in local numbering).
5953 
5954    The grid coordinates are across the entire grid, not just the local portion
5955 
5956    In Fortran idxm and idxn should be declared as
5957 $     MatStencil idxm(4,m)
5958    and the values inserted using
5959 $    idxm(MatStencil_i,1) = i
5960 $    idxm(MatStencil_j,1) = j
5961 $    idxm(MatStencil_k,1) = k
5962 $    idxm(MatStencil_c,1) = c
5963    etc
5964 
5965    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5966    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5967    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5968    DM_BOUNDARY_PERIODIC boundary type.
5969 
5970    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
5971    a single value per point) you can skip filling those indices.
5972 
5973    Level: intermediate
5974 
5975    Concepts: matrices^zeroing rows
5976 
5977 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5978           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5979 @*/
5980 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5981 {
5982   PetscInt       dim     = mat->stencil.dim;
5983   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5984   PetscInt       *dims   = mat->stencil.dims+1;
5985   PetscInt       *starts = mat->stencil.starts;
5986   PetscInt       *dxm    = (PetscInt*) rows;
5987   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5988   PetscErrorCode ierr;
5989 
5990   PetscFunctionBegin;
5991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5992   PetscValidType(mat,1);
5993   if (numRows) PetscValidIntPointer(rows,3);
5994 
5995   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5996   for (i = 0; i < numRows; ++i) {
5997     /* Skip unused dimensions (they are ordered k, j, i, c) */
5998     for (j = 0; j < 3-sdim; ++j) dxm++;
5999     /* Local index in X dir */
6000     tmp = *dxm++ - starts[0];
6001     /* Loop over remaining dimensions */
6002     for (j = 0; j < dim-1; ++j) {
6003       /* If nonlocal, set index to be negative */
6004       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6005       /* Update local index */
6006       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6007     }
6008     /* Skip component slot if necessary */
6009     if (mat->stencil.noc) dxm++;
6010     /* Local row number */
6011     if (tmp >= 0) {
6012       jdxm[numNewRows++] = tmp;
6013     }
6014   }
6015   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6016   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6017   PetscFunctionReturn(0);
6018 }
6019 
6020 /*@C
6021    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6022    of a set of rows of a matrix; using local numbering of rows.
6023 
6024    Collective on Mat
6025 
6026    Input Parameters:
6027 +  mat - the matrix
6028 .  numRows - the number of rows to remove
6029 .  rows - the global row indices
6030 .  diag - value put in all diagonals of eliminated rows
6031 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6032 -  b - optional vector of right hand side, that will be adjusted by provided solution
6033 
6034    Notes:
6035    Before calling MatZeroRowsLocal(), the user must first set the
6036    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6037 
6038    For the AIJ matrix formats this removes the old nonzero structure,
6039    but does not release memory.  For the dense and block diagonal
6040    formats this does not alter the nonzero structure.
6041 
6042    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6043    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6044    merely zeroed.
6045 
6046    The user can set a value in the diagonal entry (or for the AIJ and
6047    row formats can optionally remove the main diagonal entry from the
6048    nonzero structure as well, by passing 0.0 as the final argument).
6049 
6050    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6051    owns that are to be zeroed. This saves a global synchronization in the implementation.
6052 
6053    Level: intermediate
6054 
6055    Concepts: matrices^zeroing
6056 
6057 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6058           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6059 @*/
6060 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6061 {
6062   PetscErrorCode ierr;
6063 
6064   PetscFunctionBegin;
6065   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6066   PetscValidType(mat,1);
6067   if (numRows) PetscValidIntPointer(rows,3);
6068   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6069   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6070   MatCheckPreallocated(mat,1);
6071 
6072   if (mat->ops->zerorowslocal) {
6073     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6074   } else {
6075     IS             is, newis;
6076     const PetscInt *newRows;
6077 
6078     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6079     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6080     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6081     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6082     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6083     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6084     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6085     ierr = ISDestroy(&is);CHKERRQ(ierr);
6086   }
6087   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6088 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6089   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6090     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6091   }
6092 #endif
6093   PetscFunctionReturn(0);
6094 }
6095 
6096 /*@C
6097    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6098    of a set of rows of a matrix; using local numbering of rows.
6099 
6100    Collective on Mat
6101 
6102    Input Parameters:
6103 +  mat - the matrix
6104 .  is - index set of rows to remove
6105 .  diag - value put in all diagonals of eliminated rows
6106 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6107 -  b - optional vector of right hand side, that will be adjusted by provided solution
6108 
6109    Notes:
6110    Before calling MatZeroRowsLocalIS(), the user must first set the
6111    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6112 
6113    For the AIJ matrix formats this removes the old nonzero structure,
6114    but does not release memory.  For the dense and block diagonal
6115    formats this does not alter the nonzero structure.
6116 
6117    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6118    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6119    merely zeroed.
6120 
6121    The user can set a value in the diagonal entry (or for the AIJ and
6122    row formats can optionally remove the main diagonal entry from the
6123    nonzero structure as well, by passing 0.0 as the final argument).
6124 
6125    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6126    owns that are to be zeroed. This saves a global synchronization in the implementation.
6127 
6128    Level: intermediate
6129 
6130    Concepts: matrices^zeroing
6131 
6132 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6133           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6134 @*/
6135 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6136 {
6137   PetscErrorCode ierr;
6138   PetscInt       numRows;
6139   const PetscInt *rows;
6140 
6141   PetscFunctionBegin;
6142   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6143   PetscValidType(mat,1);
6144   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6145   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6146   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6147   MatCheckPreallocated(mat,1);
6148 
6149   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6150   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6151   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6152   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6153   PetscFunctionReturn(0);
6154 }
6155 
6156 /*@C
6157    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6158    of a set of rows and columns of a matrix; using local numbering of rows.
6159 
6160    Collective on Mat
6161 
6162    Input Parameters:
6163 +  mat - the matrix
6164 .  numRows - the number of rows to remove
6165 .  rows - the global row indices
6166 .  diag - value put in all diagonals of eliminated rows
6167 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6168 -  b - optional vector of right hand side, that will be adjusted by provided solution
6169 
6170    Notes:
6171    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6172    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6173 
6174    The user can set a value in the diagonal entry (or for the AIJ and
6175    row formats can optionally remove the main diagonal entry from the
6176    nonzero structure as well, by passing 0.0 as the final argument).
6177 
6178    Level: intermediate
6179 
6180    Concepts: matrices^zeroing
6181 
6182 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6183           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6184 @*/
6185 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6186 {
6187   PetscErrorCode ierr;
6188   IS             is, newis;
6189   const PetscInt *newRows;
6190 
6191   PetscFunctionBegin;
6192   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6193   PetscValidType(mat,1);
6194   if (numRows) PetscValidIntPointer(rows,3);
6195   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6196   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6197   MatCheckPreallocated(mat,1);
6198 
6199   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6200   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6201   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6202   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6203   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6204   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6205   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6206   ierr = ISDestroy(&is);CHKERRQ(ierr);
6207   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6208 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6209   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6210     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6211   }
6212 #endif
6213   PetscFunctionReturn(0);
6214 }
6215 
6216 /*@C
6217    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6218    of a set of rows and columns of a matrix; using local numbering of rows.
6219 
6220    Collective on Mat
6221 
6222    Input Parameters:
6223 +  mat - the matrix
6224 .  is - index set of rows to remove
6225 .  diag - value put in all diagonals of eliminated rows
6226 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6227 -  b - optional vector of right hand side, that will be adjusted by provided solution
6228 
6229    Notes:
6230    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6231    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6232 
6233    The user can set a value in the diagonal entry (or for the AIJ and
6234    row formats can optionally remove the main diagonal entry from the
6235    nonzero structure as well, by passing 0.0 as the final argument).
6236 
6237    Level: intermediate
6238 
6239    Concepts: matrices^zeroing
6240 
6241 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6242           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6243 @*/
6244 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6245 {
6246   PetscErrorCode ierr;
6247   PetscInt       numRows;
6248   const PetscInt *rows;
6249 
6250   PetscFunctionBegin;
6251   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6252   PetscValidType(mat,1);
6253   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6254   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6255   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6256   MatCheckPreallocated(mat,1);
6257 
6258   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6259   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6260   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6261   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6262   PetscFunctionReturn(0);
6263 }
6264 
6265 /*@C
6266    MatGetSize - Returns the numbers of rows and columns in a matrix.
6267 
6268    Not Collective
6269 
6270    Input Parameter:
6271 .  mat - the matrix
6272 
6273    Output Parameters:
6274 +  m - the number of global rows
6275 -  n - the number of global columns
6276 
6277    Note: both output parameters can be NULL on input.
6278 
6279    Level: beginner
6280 
6281    Concepts: matrices^size
6282 
6283 .seealso: MatGetLocalSize()
6284 @*/
6285 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6286 {
6287   PetscFunctionBegin;
6288   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6289   if (m) *m = mat->rmap->N;
6290   if (n) *n = mat->cmap->N;
6291   PetscFunctionReturn(0);
6292 }
6293 
6294 /*@C
6295    MatGetLocalSize - Returns the number of rows and columns in a matrix
6296    stored locally.  This information may be implementation dependent, so
6297    use with care.
6298 
6299    Not Collective
6300 
6301    Input Parameters:
6302 .  mat - the matrix
6303 
6304    Output Parameters:
6305 +  m - the number of local rows
6306 -  n - the number of local columns
6307 
6308    Note: both output parameters can be NULL on input.
6309 
6310    Level: beginner
6311 
6312    Concepts: matrices^local size
6313 
6314 .seealso: MatGetSize()
6315 @*/
6316 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6317 {
6318   PetscFunctionBegin;
6319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6320   if (m) PetscValidIntPointer(m,2);
6321   if (n) PetscValidIntPointer(n,3);
6322   if (m) *m = mat->rmap->n;
6323   if (n) *n = mat->cmap->n;
6324   PetscFunctionReturn(0);
6325 }
6326 
6327 /*@C
6328    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6329    this processor. (The columns of the "diagonal block")
6330 
6331    Not Collective, unless matrix has not been allocated, then collective on Mat
6332 
6333    Input Parameters:
6334 .  mat - the matrix
6335 
6336    Output Parameters:
6337 +  m - the global index of the first local column
6338 -  n - one more than the global index of the last local column
6339 
6340    Notes: both output parameters can be NULL on input.
6341 
6342    Level: developer
6343 
6344    Concepts: matrices^column ownership
6345 
6346 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6347 
6348 @*/
6349 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6350 {
6351   PetscFunctionBegin;
6352   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6353   PetscValidType(mat,1);
6354   if (m) PetscValidIntPointer(m,2);
6355   if (n) PetscValidIntPointer(n,3);
6356   MatCheckPreallocated(mat,1);
6357   if (m) *m = mat->cmap->rstart;
6358   if (n) *n = mat->cmap->rend;
6359   PetscFunctionReturn(0);
6360 }
6361 
6362 /*@C
6363    MatGetOwnershipRange - Returns the range of matrix rows owned by
6364    this processor, assuming that the matrix is laid out with the first
6365    n1 rows on the first processor, the next n2 rows on the second, etc.
6366    For certain parallel layouts this range may not be well defined.
6367 
6368    Not Collective
6369 
6370    Input Parameters:
6371 .  mat - the matrix
6372 
6373    Output Parameters:
6374 +  m - the global index of the first local row
6375 -  n - one more than the global index of the last local row
6376 
6377    Note: Both output parameters can be NULL on input.
6378 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6379 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6380 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6381 
6382    Level: beginner
6383 
6384    Concepts: matrices^row ownership
6385 
6386 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6387 
6388 @*/
6389 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6390 {
6391   PetscFunctionBegin;
6392   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6393   PetscValidType(mat,1);
6394   if (m) PetscValidIntPointer(m,2);
6395   if (n) PetscValidIntPointer(n,3);
6396   MatCheckPreallocated(mat,1);
6397   if (m) *m = mat->rmap->rstart;
6398   if (n) *n = mat->rmap->rend;
6399   PetscFunctionReturn(0);
6400 }
6401 
6402 /*@C
6403    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6404    each process
6405 
6406    Not Collective, unless matrix has not been allocated, then collective on Mat
6407 
6408    Input Parameters:
6409 .  mat - the matrix
6410 
6411    Output Parameters:
6412 .  ranges - start of each processors portion plus one more than the total length at the end
6413 
6414    Level: beginner
6415 
6416    Concepts: matrices^row ownership
6417 
6418 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6419 
6420 @*/
6421 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6422 {
6423   PetscErrorCode ierr;
6424 
6425   PetscFunctionBegin;
6426   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6427   PetscValidType(mat,1);
6428   MatCheckPreallocated(mat,1);
6429   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6430   PetscFunctionReturn(0);
6431 }
6432 
6433 /*@C
6434    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6435    this processor. (The columns of the "diagonal blocks" for each process)
6436 
6437    Not Collective, unless matrix has not been allocated, then collective on Mat
6438 
6439    Input Parameters:
6440 .  mat - the matrix
6441 
6442    Output Parameters:
6443 .  ranges - start of each processors portion plus one more then the total length at the end
6444 
6445    Level: beginner
6446 
6447    Concepts: matrices^column ownership
6448 
6449 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6450 
6451 @*/
6452 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6453 {
6454   PetscErrorCode ierr;
6455 
6456   PetscFunctionBegin;
6457   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6458   PetscValidType(mat,1);
6459   MatCheckPreallocated(mat,1);
6460   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6461   PetscFunctionReturn(0);
6462 }
6463 
6464 /*@C
6465    MatGetOwnershipIS - Get row and column ownership as index sets
6466 
6467    Not Collective
6468 
6469    Input Arguments:
6470 .  A - matrix of type Elemental
6471 
6472    Output Arguments:
6473 +  rows - rows in which this process owns elements
6474 .  cols - columns in which this process owns elements
6475 
6476    Level: intermediate
6477 
6478 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6479 @*/
6480 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6481 {
6482   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6483 
6484   PetscFunctionBegin;
6485   MatCheckPreallocated(A,1);
6486   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6487   if (f) {
6488     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6489   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6490     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6491     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6492   }
6493   PetscFunctionReturn(0);
6494 }
6495 
6496 /*@C
6497    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6498    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6499    to complete the factorization.
6500 
6501    Collective on Mat
6502 
6503    Input Parameters:
6504 +  mat - the matrix
6505 .  row - row permutation
6506 .  column - column permutation
6507 -  info - structure containing
6508 $      levels - number of levels of fill.
6509 $      expected fill - as ratio of original fill.
6510 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6511                 missing diagonal entries)
6512 
6513    Output Parameters:
6514 .  fact - new matrix that has been symbolically factored
6515 
6516    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6517 
6518    Most users should employ the simplified KSP interface for linear solvers
6519    instead of working directly with matrix algebra routines such as this.
6520    See, e.g., KSPCreate().
6521 
6522    Level: developer
6523 
6524   Concepts: matrices^symbolic LU factorization
6525   Concepts: matrices^factorization
6526   Concepts: LU^symbolic factorization
6527 
6528 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6529           MatGetOrdering(), MatFactorInfo
6530 
6531     Developer Note: fortran interface is not autogenerated as the f90
6532     interface defintion cannot be generated correctly [due to MatFactorInfo]
6533 
6534 @*/
6535 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6536 {
6537   PetscErrorCode ierr;
6538 
6539   PetscFunctionBegin;
6540   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6541   PetscValidType(mat,1);
6542   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6543   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6544   PetscValidPointer(info,4);
6545   PetscValidPointer(fact,5);
6546   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6547   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6548   if (!(fact)->ops->ilufactorsymbolic) {
6549     MatSolverType spackage;
6550     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6551     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6552   }
6553   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6554   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6555   MatCheckPreallocated(mat,2);
6556 
6557   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6558   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6559   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6560   PetscFunctionReturn(0);
6561 }
6562 
6563 /*@C
6564    MatICCFactorSymbolic - Performs symbolic incomplete
6565    Cholesky factorization for a symmetric matrix.  Use
6566    MatCholeskyFactorNumeric() to complete the factorization.
6567 
6568    Collective on Mat
6569 
6570    Input Parameters:
6571 +  mat - the matrix
6572 .  perm - row and column permutation
6573 -  info - structure containing
6574 $      levels - number of levels of fill.
6575 $      expected fill - as ratio of original fill.
6576 
6577    Output Parameter:
6578 .  fact - the factored matrix
6579 
6580    Notes:
6581    Most users should employ the KSP interface for linear solvers
6582    instead of working directly with matrix algebra routines such as this.
6583    See, e.g., KSPCreate().
6584 
6585    Level: developer
6586 
6587   Concepts: matrices^symbolic incomplete Cholesky factorization
6588   Concepts: matrices^factorization
6589   Concepts: Cholsky^symbolic factorization
6590 
6591 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6592 
6593     Developer Note: fortran interface is not autogenerated as the f90
6594     interface defintion cannot be generated correctly [due to MatFactorInfo]
6595 
6596 @*/
6597 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6598 {
6599   PetscErrorCode ierr;
6600 
6601   PetscFunctionBegin;
6602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6603   PetscValidType(mat,1);
6604   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6605   PetscValidPointer(info,3);
6606   PetscValidPointer(fact,4);
6607   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6608   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6609   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6610   if (!(fact)->ops->iccfactorsymbolic) {
6611     MatSolverType spackage;
6612     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6613     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6614   }
6615   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6616   MatCheckPreallocated(mat,2);
6617 
6618   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6619   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6620   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6621   PetscFunctionReturn(0);
6622 }
6623 
6624 /*@C
6625    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6626    points to an array of valid matrices, they may be reused to store the new
6627    submatrices.
6628 
6629    Collective on Mat
6630 
6631    Input Parameters:
6632 +  mat - the matrix
6633 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6634 .  irow, icol - index sets of rows and columns to extract
6635 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6636 
6637    Output Parameter:
6638 .  submat - the array of submatrices
6639 
6640    Notes:
6641    MatCreateSubMatrices() can extract ONLY sequential submatrices
6642    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6643    to extract a parallel submatrix.
6644 
6645    Some matrix types place restrictions on the row and column
6646    indices, such as that they be sorted or that they be equal to each other.
6647 
6648    The index sets may not have duplicate entries.
6649 
6650    When extracting submatrices from a parallel matrix, each processor can
6651    form a different submatrix by setting the rows and columns of its
6652    individual index sets according to the local submatrix desired.
6653 
6654    When finished using the submatrices, the user should destroy
6655    them with MatDestroySubMatrices().
6656 
6657    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6658    original matrix has not changed from that last call to MatCreateSubMatrices().
6659 
6660    This routine creates the matrices in submat; you should NOT create them before
6661    calling it. It also allocates the array of matrix pointers submat.
6662 
6663    For BAIJ matrices the index sets must respect the block structure, that is if they
6664    request one row/column in a block, they must request all rows/columns that are in
6665    that block. For example, if the block size is 2 you cannot request just row 0 and
6666    column 0.
6667 
6668    Fortran Note:
6669    The Fortran interface is slightly different from that given below; it
6670    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6671 
6672    Level: advanced
6673 
6674    Concepts: matrices^accessing submatrices
6675    Concepts: submatrices
6676 
6677 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6678 @*/
6679 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6680 {
6681   PetscErrorCode ierr;
6682   PetscInt       i;
6683   PetscBool      eq;
6684 
6685   PetscFunctionBegin;
6686   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6687   PetscValidType(mat,1);
6688   if (n) {
6689     PetscValidPointer(irow,3);
6690     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6691     PetscValidPointer(icol,4);
6692     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6693   }
6694   PetscValidPointer(submat,6);
6695   if (n && scall == MAT_REUSE_MATRIX) {
6696     PetscValidPointer(*submat,6);
6697     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6698   }
6699   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6700   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6701   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6702   MatCheckPreallocated(mat,1);
6703 
6704   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6705   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6706   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6707   for (i=0; i<n; i++) {
6708     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6709     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6710       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6711       if (eq) {
6712         if (mat->symmetric) {
6713           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6714         } else if (mat->hermitian) {
6715           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6716         } else if (mat->structurally_symmetric) {
6717           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6718         }
6719       }
6720     }
6721   }
6722   PetscFunctionReturn(0);
6723 }
6724 
6725 /*@C
6726    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6727 
6728    Collective on Mat
6729 
6730    Input Parameters:
6731 +  mat - the matrix
6732 .  n   - the number of submatrixes to be extracted
6733 .  irow, icol - index sets of rows and columns to extract
6734 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6735 
6736    Output Parameter:
6737 .  submat - the array of submatrices
6738 
6739    Level: advanced
6740 
6741    Concepts: matrices^accessing submatrices
6742    Concepts: submatrices
6743 
6744 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6745 @*/
6746 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6747 {
6748   PetscErrorCode ierr;
6749   PetscInt       i;
6750   PetscBool      eq;
6751 
6752   PetscFunctionBegin;
6753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6754   PetscValidType(mat,1);
6755   if (n) {
6756     PetscValidPointer(irow,3);
6757     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6758     PetscValidPointer(icol,4);
6759     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6760   }
6761   PetscValidPointer(submat,6);
6762   if (n && scall == MAT_REUSE_MATRIX) {
6763     PetscValidPointer(*submat,6);
6764     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6765   }
6766   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6767   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6768   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6769   MatCheckPreallocated(mat,1);
6770 
6771   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6772   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6773   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6774   for (i=0; i<n; i++) {
6775     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6776       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6777       if (eq) {
6778         if (mat->symmetric) {
6779           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6780         } else if (mat->hermitian) {
6781           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6782         } else if (mat->structurally_symmetric) {
6783           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6784         }
6785       }
6786     }
6787   }
6788   PetscFunctionReturn(0);
6789 }
6790 
6791 /*@C
6792    MatDestroyMatrices - Destroys an array of matrices.
6793 
6794    Collective on Mat
6795 
6796    Input Parameters:
6797 +  n - the number of local matrices
6798 -  mat - the matrices (note that this is a pointer to the array of matrices)
6799 
6800    Level: advanced
6801 
6802     Notes: Frees not only the matrices, but also the array that contains the matrices
6803            In Fortran will not free the array.
6804 
6805 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6806 @*/
6807 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6808 {
6809   PetscErrorCode ierr;
6810   PetscInt       i;
6811 
6812   PetscFunctionBegin;
6813   if (!*mat) PetscFunctionReturn(0);
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   for (i=0; i<n; i++) {
6818     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6819   }
6820 
6821   /* memory is allocated even if n = 0 */
6822   ierr = PetscFree(*mat);CHKERRQ(ierr);
6823   PetscFunctionReturn(0);
6824 }
6825 
6826 /*@C
6827    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6828 
6829    Collective on Mat
6830 
6831    Input Parameters:
6832 +  n - the number of local matrices
6833 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6834                        sequence of MatCreateSubMatrices())
6835 
6836    Level: advanced
6837 
6838     Notes: Frees not only the matrices, but also the array that contains the matrices
6839            In Fortran will not free the array.
6840 
6841 .seealso: MatCreateSubMatrices()
6842 @*/
6843 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6844 {
6845   PetscErrorCode ierr;
6846   Mat            mat0;
6847 
6848   PetscFunctionBegin;
6849   if (!*mat) PetscFunctionReturn(0);
6850   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6851   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6852   PetscValidPointer(mat,2);
6853 
6854   mat0 = (*mat)[0];
6855   if (mat0 && mat0->ops->destroysubmatrices) {
6856     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6857   } else {
6858     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6859   }
6860   PetscFunctionReturn(0);
6861 }
6862 
6863 /*@C
6864    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6865 
6866    Collective on Mat
6867 
6868    Input Parameters:
6869 .  mat - the matrix
6870 
6871    Output Parameter:
6872 .  matstruct - the sequential matrix with the nonzero structure of mat
6873 
6874   Level: intermediate
6875 
6876 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6877 @*/
6878 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6879 {
6880   PetscErrorCode ierr;
6881 
6882   PetscFunctionBegin;
6883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6884   PetscValidPointer(matstruct,2);
6885 
6886   PetscValidType(mat,1);
6887   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6888   MatCheckPreallocated(mat,1);
6889 
6890   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6891   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6892   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6893   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6894   PetscFunctionReturn(0);
6895 }
6896 
6897 /*@C
6898    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6899 
6900    Collective on Mat
6901 
6902    Input Parameters:
6903 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6904                        sequence of MatGetSequentialNonzeroStructure())
6905 
6906    Level: advanced
6907 
6908     Notes: Frees not only the matrices, but also the array that contains the matrices
6909 
6910 .seealso: MatGetSeqNonzeroStructure()
6911 @*/
6912 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6913 {
6914   PetscErrorCode ierr;
6915 
6916   PetscFunctionBegin;
6917   PetscValidPointer(mat,1);
6918   ierr = MatDestroy(mat);CHKERRQ(ierr);
6919   PetscFunctionReturn(0);
6920 }
6921 
6922 /*@
6923    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6924    replaces the index sets by larger ones that represent submatrices with
6925    additional overlap.
6926 
6927    Collective on Mat
6928 
6929    Input Parameters:
6930 +  mat - the matrix
6931 .  n   - the number of index sets
6932 .  is  - the array of index sets (these index sets will changed during the call)
6933 -  ov  - the additional overlap requested
6934 
6935    Options Database:
6936 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6937 
6938    Level: developer
6939 
6940    Concepts: overlap
6941    Concepts: ASM^computing overlap
6942 
6943 .seealso: MatCreateSubMatrices()
6944 @*/
6945 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6946 {
6947   PetscErrorCode ierr;
6948 
6949   PetscFunctionBegin;
6950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6951   PetscValidType(mat,1);
6952   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6953   if (n) {
6954     PetscValidPointer(is,3);
6955     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6956   }
6957   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6958   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6959   MatCheckPreallocated(mat,1);
6960 
6961   if (!ov) PetscFunctionReturn(0);
6962   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6963   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6964   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6965   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6966   PetscFunctionReturn(0);
6967 }
6968 
6969 
6970 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6971 
6972 /*@
6973    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6974    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6975    additional overlap.
6976 
6977    Collective on Mat
6978 
6979    Input Parameters:
6980 +  mat - the matrix
6981 .  n   - the number of index sets
6982 .  is  - the array of index sets (these index sets will changed during the call)
6983 -  ov  - the additional overlap requested
6984 
6985    Options Database:
6986 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6987 
6988    Level: developer
6989 
6990    Concepts: overlap
6991    Concepts: ASM^computing overlap
6992 
6993 .seealso: MatCreateSubMatrices()
6994 @*/
6995 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6996 {
6997   PetscInt       i;
6998   PetscErrorCode ierr;
6999 
7000   PetscFunctionBegin;
7001   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7002   PetscValidType(mat,1);
7003   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7004   if (n) {
7005     PetscValidPointer(is,3);
7006     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7007   }
7008   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7009   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7010   MatCheckPreallocated(mat,1);
7011   if (!ov) PetscFunctionReturn(0);
7012   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7013   for(i=0; i<n; i++){
7014 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7015   }
7016   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7017   PetscFunctionReturn(0);
7018 }
7019 
7020 
7021 
7022 
7023 /*@
7024    MatGetBlockSize - Returns the matrix block size.
7025 
7026    Not Collective
7027 
7028    Input Parameter:
7029 .  mat - the matrix
7030 
7031    Output Parameter:
7032 .  bs - block size
7033 
7034    Notes:
7035     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7036 
7037    If the block size has not been set yet this routine returns 1.
7038 
7039    Level: intermediate
7040 
7041    Concepts: matrices^block size
7042 
7043 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7044 @*/
7045 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7046 {
7047   PetscFunctionBegin;
7048   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7049   PetscValidIntPointer(bs,2);
7050   *bs = PetscAbs(mat->rmap->bs);
7051   PetscFunctionReturn(0);
7052 }
7053 
7054 /*@
7055    MatGetBlockSizes - Returns the matrix block row and column sizes.
7056 
7057    Not Collective
7058 
7059    Input Parameter:
7060 .  mat - the matrix
7061 
7062    Output Parameter:
7063 .  rbs - row block size
7064 .  cbs - column block size
7065 
7066    Notes:
7067     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7068     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7069 
7070    If a block size has not been set yet this routine returns 1.
7071 
7072    Level: intermediate
7073 
7074    Concepts: matrices^block size
7075 
7076 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7077 @*/
7078 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7079 {
7080   PetscFunctionBegin;
7081   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7082   if (rbs) PetscValidIntPointer(rbs,2);
7083   if (cbs) PetscValidIntPointer(cbs,3);
7084   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7085   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7086   PetscFunctionReturn(0);
7087 }
7088 
7089 /*@
7090    MatSetBlockSize - Sets the matrix block size.
7091 
7092    Logically Collective on Mat
7093 
7094    Input Parameters:
7095 +  mat - the matrix
7096 -  bs - block size
7097 
7098    Notes:
7099     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7100     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7101 
7102     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7103     is compatible with the matrix local sizes.
7104 
7105    Level: intermediate
7106 
7107    Concepts: matrices^block size
7108 
7109 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7110 @*/
7111 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7112 {
7113   PetscErrorCode ierr;
7114 
7115   PetscFunctionBegin;
7116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7117   PetscValidLogicalCollectiveInt(mat,bs,2);
7118   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7119   PetscFunctionReturn(0);
7120 }
7121 
7122 /*@
7123    MatSetBlockSizes - Sets the matrix block row and column sizes.
7124 
7125    Logically Collective on Mat
7126 
7127    Input Parameters:
7128 +  mat - the matrix
7129 -  rbs - row block size
7130 -  cbs - column block size
7131 
7132    Notes:
7133     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7134     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7135     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7136 
7137     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7138     are compatible with the matrix local sizes.
7139 
7140     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7141 
7142    Level: intermediate
7143 
7144    Concepts: matrices^block size
7145 
7146 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7147 @*/
7148 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7149 {
7150   PetscErrorCode ierr;
7151 
7152   PetscFunctionBegin;
7153   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7154   PetscValidLogicalCollectiveInt(mat,rbs,2);
7155   PetscValidLogicalCollectiveInt(mat,cbs,3);
7156   if (mat->ops->setblocksizes) {
7157     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7158   }
7159   if (mat->rmap->refcnt) {
7160     ISLocalToGlobalMapping l2g = NULL;
7161     PetscLayout            nmap = NULL;
7162 
7163     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7164     if (mat->rmap->mapping) {
7165       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7166     }
7167     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7168     mat->rmap = nmap;
7169     mat->rmap->mapping = l2g;
7170   }
7171   if (mat->cmap->refcnt) {
7172     ISLocalToGlobalMapping l2g = NULL;
7173     PetscLayout            nmap = NULL;
7174 
7175     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7176     if (mat->cmap->mapping) {
7177       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7178     }
7179     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7180     mat->cmap = nmap;
7181     mat->cmap->mapping = l2g;
7182   }
7183   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7184   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7185   PetscFunctionReturn(0);
7186 }
7187 
7188 /*@
7189    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7190 
7191    Logically Collective on Mat
7192 
7193    Input Parameters:
7194 +  mat - the matrix
7195 .  fromRow - matrix from which to copy row block size
7196 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7197 
7198    Level: developer
7199 
7200    Concepts: matrices^block size
7201 
7202 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7203 @*/
7204 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7205 {
7206   PetscErrorCode ierr;
7207 
7208   PetscFunctionBegin;
7209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7210   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7211   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7212   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7213   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7214   PetscFunctionReturn(0);
7215 }
7216 
7217 /*@
7218    MatResidual - Default routine to calculate the residual.
7219 
7220    Collective on Mat and Vec
7221 
7222    Input Parameters:
7223 +  mat - the matrix
7224 .  b   - the right-hand-side
7225 -  x   - the approximate solution
7226 
7227    Output Parameter:
7228 .  r - location to store the residual
7229 
7230    Level: developer
7231 
7232 .keywords: MG, default, multigrid, residual
7233 
7234 .seealso: PCMGSetResidual()
7235 @*/
7236 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7237 {
7238   PetscErrorCode ierr;
7239 
7240   PetscFunctionBegin;
7241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7242   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7243   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7244   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7245   PetscValidType(mat,1);
7246   MatCheckPreallocated(mat,1);
7247   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7248   if (!mat->ops->residual) {
7249     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7250     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7251   } else {
7252     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7253   }
7254   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7255   PetscFunctionReturn(0);
7256 }
7257 
7258 /*@C
7259     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7260 
7261    Collective on Mat
7262 
7263     Input Parameters:
7264 +   mat - the matrix
7265 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7266 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7267 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7268                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7269                  always used.
7270 
7271     Output Parameters:
7272 +   n - number of rows in the (possibly compressed) matrix
7273 .   ia - the row pointers [of length n+1]
7274 .   ja - the column indices
7275 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7276            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7277 
7278     Level: developer
7279 
7280     Notes:
7281     You CANNOT change any of the ia[] or ja[] values.
7282 
7283     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7284 
7285     Fortran Notes:
7286     In Fortran use
7287 $
7288 $      PetscInt ia(1), ja(1)
7289 $      PetscOffset iia, jja
7290 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7291 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7292 
7293      or
7294 $
7295 $    PetscInt, pointer :: ia(:),ja(:)
7296 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7297 $    ! Access the ith and jth entries via ia(i) and ja(j)
7298 
7299 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7300 @*/
7301 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7302 {
7303   PetscErrorCode ierr;
7304 
7305   PetscFunctionBegin;
7306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7307   PetscValidType(mat,1);
7308   PetscValidIntPointer(n,5);
7309   if (ia) PetscValidIntPointer(ia,6);
7310   if (ja) PetscValidIntPointer(ja,7);
7311   PetscValidIntPointer(done,8);
7312   MatCheckPreallocated(mat,1);
7313   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7314   else {
7315     *done = PETSC_TRUE;
7316     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7317     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7318     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7319   }
7320   PetscFunctionReturn(0);
7321 }
7322 
7323 /*@C
7324     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7325 
7326     Collective on Mat
7327 
7328     Input Parameters:
7329 +   mat - the matrix
7330 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7331 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7332                 symmetrized
7333 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7334                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7335                  always used.
7336 .   n - number of columns in the (possibly compressed) matrix
7337 .   ia - the column pointers
7338 -   ja - the row indices
7339 
7340     Output Parameters:
7341 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7342 
7343     Note:
7344     This routine zeros out n, ia, and ja. This is to prevent accidental
7345     us of the array after it has been restored. If you pass NULL, it will
7346     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7347 
7348     Level: developer
7349 
7350 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7351 @*/
7352 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7353 {
7354   PetscErrorCode ierr;
7355 
7356   PetscFunctionBegin;
7357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7358   PetscValidType(mat,1);
7359   PetscValidIntPointer(n,4);
7360   if (ia) PetscValidIntPointer(ia,5);
7361   if (ja) PetscValidIntPointer(ja,6);
7362   PetscValidIntPointer(done,7);
7363   MatCheckPreallocated(mat,1);
7364   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7365   else {
7366     *done = PETSC_TRUE;
7367     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7368   }
7369   PetscFunctionReturn(0);
7370 }
7371 
7372 /*@C
7373     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7374     MatGetRowIJ().
7375 
7376     Collective on Mat
7377 
7378     Input Parameters:
7379 +   mat - the matrix
7380 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7381 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7382                 symmetrized
7383 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7384                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7385                  always used.
7386 .   n - size of (possibly compressed) matrix
7387 .   ia - the row pointers
7388 -   ja - the column indices
7389 
7390     Output Parameters:
7391 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7392 
7393     Note:
7394     This routine zeros out n, ia, and ja. This is to prevent accidental
7395     us of the array after it has been restored. If you pass NULL, it will
7396     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7397 
7398     Level: developer
7399 
7400 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7401 @*/
7402 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7403 {
7404   PetscErrorCode ierr;
7405 
7406   PetscFunctionBegin;
7407   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7408   PetscValidType(mat,1);
7409   if (ia) PetscValidIntPointer(ia,6);
7410   if (ja) PetscValidIntPointer(ja,7);
7411   PetscValidIntPointer(done,8);
7412   MatCheckPreallocated(mat,1);
7413 
7414   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7415   else {
7416     *done = PETSC_TRUE;
7417     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7418     if (n)  *n = 0;
7419     if (ia) *ia = NULL;
7420     if (ja) *ja = NULL;
7421   }
7422   PetscFunctionReturn(0);
7423 }
7424 
7425 /*@C
7426     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7427     MatGetColumnIJ().
7428 
7429     Collective on Mat
7430 
7431     Input Parameters:
7432 +   mat - the matrix
7433 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7434 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7435                 symmetrized
7436 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7437                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7438                  always used.
7439 
7440     Output Parameters:
7441 +   n - size of (possibly compressed) matrix
7442 .   ia - the column pointers
7443 .   ja - the row indices
7444 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7445 
7446     Level: developer
7447 
7448 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7449 @*/
7450 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7451 {
7452   PetscErrorCode ierr;
7453 
7454   PetscFunctionBegin;
7455   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7456   PetscValidType(mat,1);
7457   if (ia) PetscValidIntPointer(ia,5);
7458   if (ja) PetscValidIntPointer(ja,6);
7459   PetscValidIntPointer(done,7);
7460   MatCheckPreallocated(mat,1);
7461 
7462   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7463   else {
7464     *done = PETSC_TRUE;
7465     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7466     if (n)  *n = 0;
7467     if (ia) *ia = NULL;
7468     if (ja) *ja = NULL;
7469   }
7470   PetscFunctionReturn(0);
7471 }
7472 
7473 /*@C
7474     MatColoringPatch -Used inside matrix coloring routines that
7475     use MatGetRowIJ() and/or MatGetColumnIJ().
7476 
7477     Collective on Mat
7478 
7479     Input Parameters:
7480 +   mat - the matrix
7481 .   ncolors - max color value
7482 .   n   - number of entries in colorarray
7483 -   colorarray - array indicating color for each column
7484 
7485     Output Parameters:
7486 .   iscoloring - coloring generated using colorarray information
7487 
7488     Level: developer
7489 
7490 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7491 
7492 @*/
7493 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7494 {
7495   PetscErrorCode ierr;
7496 
7497   PetscFunctionBegin;
7498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7499   PetscValidType(mat,1);
7500   PetscValidIntPointer(colorarray,4);
7501   PetscValidPointer(iscoloring,5);
7502   MatCheckPreallocated(mat,1);
7503 
7504   if (!mat->ops->coloringpatch) {
7505     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7506   } else {
7507     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7508   }
7509   PetscFunctionReturn(0);
7510 }
7511 
7512 
7513 /*@
7514    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7515 
7516    Logically Collective on Mat
7517 
7518    Input Parameter:
7519 .  mat - the factored matrix to be reset
7520 
7521    Notes:
7522    This routine should be used only with factored matrices formed by in-place
7523    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7524    format).  This option can save memory, for example, when solving nonlinear
7525    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7526    ILU(0) preconditioner.
7527 
7528    Note that one can specify in-place ILU(0) factorization by calling
7529 .vb
7530      PCType(pc,PCILU);
7531      PCFactorSeUseInPlace(pc);
7532 .ve
7533    or by using the options -pc_type ilu -pc_factor_in_place
7534 
7535    In-place factorization ILU(0) can also be used as a local
7536    solver for the blocks within the block Jacobi or additive Schwarz
7537    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7538    for details on setting local solver options.
7539 
7540    Most users should employ the simplified KSP interface for linear solvers
7541    instead of working directly with matrix algebra routines such as this.
7542    See, e.g., KSPCreate().
7543 
7544    Level: developer
7545 
7546 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7547 
7548    Concepts: matrices^unfactored
7549 
7550 @*/
7551 PetscErrorCode MatSetUnfactored(Mat mat)
7552 {
7553   PetscErrorCode ierr;
7554 
7555   PetscFunctionBegin;
7556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7557   PetscValidType(mat,1);
7558   MatCheckPreallocated(mat,1);
7559   mat->factortype = MAT_FACTOR_NONE;
7560   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7561   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7562   PetscFunctionReturn(0);
7563 }
7564 
7565 /*MC
7566     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7567 
7568     Synopsis:
7569     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7570 
7571     Not collective
7572 
7573     Input Parameter:
7574 .   x - matrix
7575 
7576     Output Parameters:
7577 +   xx_v - the Fortran90 pointer to the array
7578 -   ierr - error code
7579 
7580     Example of Usage:
7581 .vb
7582       PetscScalar, pointer xx_v(:,:)
7583       ....
7584       call MatDenseGetArrayF90(x,xx_v,ierr)
7585       a = xx_v(3)
7586       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7587 .ve
7588 
7589     Level: advanced
7590 
7591 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7592 
7593     Concepts: matrices^accessing array
7594 
7595 M*/
7596 
7597 /*MC
7598     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7599     accessed with MatDenseGetArrayF90().
7600 
7601     Synopsis:
7602     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7603 
7604     Not collective
7605 
7606     Input Parameters:
7607 +   x - matrix
7608 -   xx_v - the Fortran90 pointer to the array
7609 
7610     Output Parameter:
7611 .   ierr - error code
7612 
7613     Example of Usage:
7614 .vb
7615        PetscScalar, pointer xx_v(:,:)
7616        ....
7617        call MatDenseGetArrayF90(x,xx_v,ierr)
7618        a = xx_v(3)
7619        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7620 .ve
7621 
7622     Level: advanced
7623 
7624 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7625 
7626 M*/
7627 
7628 
7629 /*MC
7630     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7631 
7632     Synopsis:
7633     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7634 
7635     Not collective
7636 
7637     Input Parameter:
7638 .   x - matrix
7639 
7640     Output Parameters:
7641 +   xx_v - the Fortran90 pointer to the array
7642 -   ierr - error code
7643 
7644     Example of Usage:
7645 .vb
7646       PetscScalar, pointer xx_v(:)
7647       ....
7648       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7649       a = xx_v(3)
7650       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7651 .ve
7652 
7653     Level: advanced
7654 
7655 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7656 
7657     Concepts: matrices^accessing array
7658 
7659 M*/
7660 
7661 /*MC
7662     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7663     accessed with MatSeqAIJGetArrayF90().
7664 
7665     Synopsis:
7666     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7667 
7668     Not collective
7669 
7670     Input Parameters:
7671 +   x - matrix
7672 -   xx_v - the Fortran90 pointer to the array
7673 
7674     Output Parameter:
7675 .   ierr - error code
7676 
7677     Example of Usage:
7678 .vb
7679        PetscScalar, pointer xx_v(:)
7680        ....
7681        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7682        a = xx_v(3)
7683        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7684 .ve
7685 
7686     Level: advanced
7687 
7688 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7689 
7690 M*/
7691 
7692 
7693 /*@
7694     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7695                       as the original matrix.
7696 
7697     Collective on Mat
7698 
7699     Input Parameters:
7700 +   mat - the original matrix
7701 .   isrow - parallel IS containing the rows this processor should obtain
7702 .   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.
7703 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7704 
7705     Output Parameter:
7706 .   newmat - the new submatrix, of the same type as the old
7707 
7708     Level: advanced
7709 
7710     Notes:
7711     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7712 
7713     Some matrix types place restrictions on the row and column indices, such
7714     as that they be sorted or that they be equal to each other.
7715 
7716     The index sets may not have duplicate entries.
7717 
7718       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7719    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7720    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7721    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7722    you are finished using it.
7723 
7724     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7725     the input matrix.
7726 
7727     If iscol is NULL then all columns are obtained (not supported in Fortran).
7728 
7729    Example usage:
7730    Consider the following 8x8 matrix with 34 non-zero values, that is
7731    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7732    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7733    as follows:
7734 
7735 .vb
7736             1  2  0  |  0  3  0  |  0  4
7737     Proc0   0  5  6  |  7  0  0  |  8  0
7738             9  0 10  | 11  0  0  | 12  0
7739     -------------------------------------
7740            13  0 14  | 15 16 17  |  0  0
7741     Proc1   0 18  0  | 19 20 21  |  0  0
7742             0  0  0  | 22 23  0  | 24  0
7743     -------------------------------------
7744     Proc2  25 26 27  |  0  0 28  | 29  0
7745            30  0  0  | 31 32 33  |  0 34
7746 .ve
7747 
7748     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7749 
7750 .vb
7751             2  0  |  0  3  0  |  0
7752     Proc0   5  6  |  7  0  0  |  8
7753     -------------------------------
7754     Proc1  18  0  | 19 20 21  |  0
7755     -------------------------------
7756     Proc2  26 27  |  0  0 28  | 29
7757             0  0  | 31 32 33  |  0
7758 .ve
7759 
7760 
7761     Concepts: matrices^submatrices
7762 
7763 .seealso: MatCreateSubMatrices()
7764 @*/
7765 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7766 {
7767   PetscErrorCode ierr;
7768   PetscMPIInt    size;
7769   Mat            *local;
7770   IS             iscoltmp;
7771 
7772   PetscFunctionBegin;
7773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7774   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7775   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7776   PetscValidPointer(newmat,5);
7777   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7778   PetscValidType(mat,1);
7779   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7780   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7781 
7782   MatCheckPreallocated(mat,1);
7783   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7784 
7785   if (!iscol || isrow == iscol) {
7786     PetscBool   stride;
7787     PetscMPIInt grabentirematrix = 0,grab;
7788     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7789     if (stride) {
7790       PetscInt first,step,n,rstart,rend;
7791       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7792       if (step == 1) {
7793         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7794         if (rstart == first) {
7795           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7796           if (n == rend-rstart) {
7797             grabentirematrix = 1;
7798           }
7799         }
7800       }
7801     }
7802     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7803     if (grab) {
7804       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7805       if (cll == MAT_INITIAL_MATRIX) {
7806         *newmat = mat;
7807         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7808       }
7809       PetscFunctionReturn(0);
7810     }
7811   }
7812 
7813   if (!iscol) {
7814     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7815   } else {
7816     iscoltmp = iscol;
7817   }
7818 
7819   /* if original matrix is on just one processor then use submatrix generated */
7820   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7821     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7822     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7823     PetscFunctionReturn(0);
7824   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7825     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7826     *newmat = *local;
7827     ierr    = PetscFree(local);CHKERRQ(ierr);
7828     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7829     PetscFunctionReturn(0);
7830   } else if (!mat->ops->createsubmatrix) {
7831     /* Create a new matrix type that implements the operation using the full matrix */
7832     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7833     switch (cll) {
7834     case MAT_INITIAL_MATRIX:
7835       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7836       break;
7837     case MAT_REUSE_MATRIX:
7838       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7839       break;
7840     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7841     }
7842     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7843     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7844     PetscFunctionReturn(0);
7845   }
7846 
7847   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7848   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7849   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7850   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7851   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7852   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7853   PetscFunctionReturn(0);
7854 }
7855 
7856 /*@
7857    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7858    used during the assembly process to store values that belong to
7859    other processors.
7860 
7861    Not Collective
7862 
7863    Input Parameters:
7864 +  mat   - the matrix
7865 .  size  - the initial size of the stash.
7866 -  bsize - the initial size of the block-stash(if used).
7867 
7868    Options Database Keys:
7869 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7870 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7871 
7872    Level: intermediate
7873 
7874    Notes:
7875      The block-stash is used for values set with MatSetValuesBlocked() while
7876      the stash is used for values set with MatSetValues()
7877 
7878      Run with the option -info and look for output of the form
7879      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7880      to determine the appropriate value, MM, to use for size and
7881      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7882      to determine the value, BMM to use for bsize
7883 
7884    Concepts: stash^setting matrix size
7885    Concepts: matrices^stash
7886 
7887 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7888 
7889 @*/
7890 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7891 {
7892   PetscErrorCode ierr;
7893 
7894   PetscFunctionBegin;
7895   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7896   PetscValidType(mat,1);
7897   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7898   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7899   PetscFunctionReturn(0);
7900 }
7901 
7902 /*@
7903    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7904      the matrix
7905 
7906    Neighbor-wise Collective on Mat
7907 
7908    Input Parameters:
7909 +  mat   - the matrix
7910 .  x,y - the vectors
7911 -  w - where the result is stored
7912 
7913    Level: intermediate
7914 
7915    Notes:
7916     w may be the same vector as y.
7917 
7918     This allows one to use either the restriction or interpolation (its transpose)
7919     matrix to do the interpolation
7920 
7921     Concepts: interpolation
7922 
7923 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7924 
7925 @*/
7926 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7927 {
7928   PetscErrorCode ierr;
7929   PetscInt       M,N,Ny;
7930 
7931   PetscFunctionBegin;
7932   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7933   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7934   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7935   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7936   PetscValidType(A,1);
7937   MatCheckPreallocated(A,1);
7938   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7939   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7940   if (M == Ny) {
7941     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7942   } else {
7943     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7944   }
7945   PetscFunctionReturn(0);
7946 }
7947 
7948 /*@
7949    MatInterpolate - y = A*x or A'*x depending on the shape of
7950      the matrix
7951 
7952    Neighbor-wise Collective on Mat
7953 
7954    Input Parameters:
7955 +  mat   - the matrix
7956 -  x,y - the vectors
7957 
7958    Level: intermediate
7959 
7960    Notes:
7961     This allows one to use either the restriction or interpolation (its transpose)
7962     matrix to do the interpolation
7963 
7964    Concepts: matrices^interpolation
7965 
7966 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7967 
7968 @*/
7969 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7970 {
7971   PetscErrorCode ierr;
7972   PetscInt       M,N,Ny;
7973 
7974   PetscFunctionBegin;
7975   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7976   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7977   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7978   PetscValidType(A,1);
7979   MatCheckPreallocated(A,1);
7980   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7981   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7982   if (M == Ny) {
7983     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7984   } else {
7985     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7986   }
7987   PetscFunctionReturn(0);
7988 }
7989 
7990 /*@
7991    MatRestrict - y = A*x or A'*x
7992 
7993    Neighbor-wise Collective on Mat
7994 
7995    Input Parameters:
7996 +  mat   - the matrix
7997 -  x,y - the vectors
7998 
7999    Level: intermediate
8000 
8001    Notes:
8002     This allows one to use either the restriction or interpolation (its transpose)
8003     matrix to do the restriction
8004 
8005    Concepts: matrices^restriction
8006 
8007 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8008 
8009 @*/
8010 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8011 {
8012   PetscErrorCode ierr;
8013   PetscInt       M,N,Ny;
8014 
8015   PetscFunctionBegin;
8016   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8017   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8018   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8019   PetscValidType(A,1);
8020   MatCheckPreallocated(A,1);
8021 
8022   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8023   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8024   if (M == Ny) {
8025     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8026   } else {
8027     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8028   }
8029   PetscFunctionReturn(0);
8030 }
8031 
8032 /*@C
8033    MatGetNullSpace - retrieves the null space to a matrix.
8034 
8035    Logically Collective on Mat and MatNullSpace
8036 
8037    Input Parameters:
8038 +  mat - the matrix
8039 -  nullsp - the null space object
8040 
8041    Level: developer
8042 
8043    Concepts: null space^attaching to matrix
8044 
8045 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8046 @*/
8047 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8048 {
8049   PetscFunctionBegin;
8050   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8051   PetscValidPointer(nullsp,2);
8052   *nullsp = mat->nullsp;
8053   PetscFunctionReturn(0);
8054 }
8055 
8056 /*@C
8057    MatSetNullSpace - attaches a null space to a matrix.
8058 
8059    Logically Collective on Mat and MatNullSpace
8060 
8061    Input Parameters:
8062 +  mat - the matrix
8063 -  nullsp - the null space object
8064 
8065    Level: advanced
8066 
8067    Notes:
8068       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8069 
8070       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8071       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8072 
8073       You can remove the null space by calling this routine with an nullsp of NULL
8074 
8075 
8076       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8077    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).
8078    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
8079    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
8080    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).
8081 
8082       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8083 
8084     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
8085     routine also automatically calls MatSetTransposeNullSpace().
8086 
8087    Concepts: null space^attaching to matrix
8088 
8089 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8090 @*/
8091 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8092 {
8093   PetscErrorCode ierr;
8094 
8095   PetscFunctionBegin;
8096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8097   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8098   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8099   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8100   mat->nullsp = nullsp;
8101   if (mat->symmetric_set && mat->symmetric) {
8102     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8103   }
8104   PetscFunctionReturn(0);
8105 }
8106 
8107 /*@
8108    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8109 
8110    Logically Collective on Mat and MatNullSpace
8111 
8112    Input Parameters:
8113 +  mat - the matrix
8114 -  nullsp - the null space object
8115 
8116    Level: developer
8117 
8118    Concepts: null space^attaching to matrix
8119 
8120 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8121 @*/
8122 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8123 {
8124   PetscFunctionBegin;
8125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8126   PetscValidType(mat,1);
8127   PetscValidPointer(nullsp,2);
8128   *nullsp = mat->transnullsp;
8129   PetscFunctionReturn(0);
8130 }
8131 
8132 /*@
8133    MatSetTransposeNullSpace - attaches a null space to a matrix.
8134 
8135    Logically Collective on Mat and MatNullSpace
8136 
8137    Input Parameters:
8138 +  mat - the matrix
8139 -  nullsp - the null space object
8140 
8141    Level: advanced
8142 
8143    Notes:
8144       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.
8145       You must also call MatSetNullSpace()
8146 
8147 
8148       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8149    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).
8150    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
8151    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
8152    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).
8153 
8154       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8155 
8156    Concepts: null space^attaching to matrix
8157 
8158 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8159 @*/
8160 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8161 {
8162   PetscErrorCode ierr;
8163 
8164   PetscFunctionBegin;
8165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8166   PetscValidType(mat,1);
8167   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8168   MatCheckPreallocated(mat,1);
8169   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8170   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8171   mat->transnullsp = nullsp;
8172   PetscFunctionReturn(0);
8173 }
8174 
8175 /*@
8176    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8177         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8178 
8179    Logically Collective on Mat and MatNullSpace
8180 
8181    Input Parameters:
8182 +  mat - the matrix
8183 -  nullsp - the null space object
8184 
8185    Level: advanced
8186 
8187    Notes:
8188       Overwrites any previous near null space that may have been attached
8189 
8190       You can remove the null space by calling this routine with an nullsp of NULL
8191 
8192    Concepts: null space^attaching to matrix
8193 
8194 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8195 @*/
8196 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8197 {
8198   PetscErrorCode ierr;
8199 
8200   PetscFunctionBegin;
8201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8202   PetscValidType(mat,1);
8203   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8204   MatCheckPreallocated(mat,1);
8205   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8206   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8207   mat->nearnullsp = nullsp;
8208   PetscFunctionReturn(0);
8209 }
8210 
8211 /*@
8212    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8213 
8214    Not Collective
8215 
8216    Input Parameters:
8217 .  mat - the matrix
8218 
8219    Output Parameters:
8220 .  nullsp - the null space object, NULL if not set
8221 
8222    Level: developer
8223 
8224    Concepts: null space^attaching to matrix
8225 
8226 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8227 @*/
8228 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8229 {
8230   PetscFunctionBegin;
8231   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8232   PetscValidType(mat,1);
8233   PetscValidPointer(nullsp,2);
8234   MatCheckPreallocated(mat,1);
8235   *nullsp = mat->nearnullsp;
8236   PetscFunctionReturn(0);
8237 }
8238 
8239 /*@C
8240    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8241 
8242    Collective on Mat
8243 
8244    Input Parameters:
8245 +  mat - the matrix
8246 .  row - row/column permutation
8247 .  fill - expected fill factor >= 1.0
8248 -  level - level of fill, for ICC(k)
8249 
8250    Notes:
8251    Probably really in-place only when level of fill is zero, otherwise allocates
8252    new space to store factored matrix and deletes previous memory.
8253 
8254    Most users should employ the simplified KSP interface for linear solvers
8255    instead of working directly with matrix algebra routines such as this.
8256    See, e.g., KSPCreate().
8257 
8258    Level: developer
8259 
8260    Concepts: matrices^incomplete Cholesky factorization
8261    Concepts: Cholesky factorization
8262 
8263 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8264 
8265     Developer Note: fortran interface is not autogenerated as the f90
8266     interface defintion cannot be generated correctly [due to MatFactorInfo]
8267 
8268 @*/
8269 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8270 {
8271   PetscErrorCode ierr;
8272 
8273   PetscFunctionBegin;
8274   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8275   PetscValidType(mat,1);
8276   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8277   PetscValidPointer(info,3);
8278   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8279   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8280   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8281   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8282   MatCheckPreallocated(mat,1);
8283   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8284   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8285   PetscFunctionReturn(0);
8286 }
8287 
8288 /*@
8289    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8290          ghosted ones.
8291 
8292    Not Collective
8293 
8294    Input Parameters:
8295 +  mat - the matrix
8296 -  diag = the diagonal values, including ghost ones
8297 
8298    Level: developer
8299 
8300    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8301 
8302 .seealso: MatDiagonalScale()
8303 @*/
8304 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8305 {
8306   PetscErrorCode ierr;
8307   PetscMPIInt    size;
8308 
8309   PetscFunctionBegin;
8310   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8311   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8312   PetscValidType(mat,1);
8313 
8314   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8315   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8316   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8317   if (size == 1) {
8318     PetscInt n,m;
8319     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8320     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8321     if (m == n) {
8322       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8323     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8324   } else {
8325     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8326   }
8327   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8328   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8329   PetscFunctionReturn(0);
8330 }
8331 
8332 /*@
8333    MatGetInertia - Gets the inertia from a factored matrix
8334 
8335    Collective on Mat
8336 
8337    Input Parameter:
8338 .  mat - the matrix
8339 
8340    Output Parameters:
8341 +   nneg - number of negative eigenvalues
8342 .   nzero - number of zero eigenvalues
8343 -   npos - number of positive eigenvalues
8344 
8345    Level: advanced
8346 
8347    Notes: Matrix must have been factored by MatCholeskyFactor()
8348 
8349 
8350 @*/
8351 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8352 {
8353   PetscErrorCode ierr;
8354 
8355   PetscFunctionBegin;
8356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8357   PetscValidType(mat,1);
8358   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8359   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8360   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8361   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8362   PetscFunctionReturn(0);
8363 }
8364 
8365 /* ----------------------------------------------------------------*/
8366 /*@C
8367    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8368 
8369    Neighbor-wise Collective on Mat and Vecs
8370 
8371    Input Parameters:
8372 +  mat - the factored matrix
8373 -  b - the right-hand-side vectors
8374 
8375    Output Parameter:
8376 .  x - the result vectors
8377 
8378    Notes:
8379    The vectors b and x cannot be the same.  I.e., one cannot
8380    call MatSolves(A,x,x).
8381 
8382    Notes:
8383    Most users should employ the simplified KSP interface for linear solvers
8384    instead of working directly with matrix algebra routines such as this.
8385    See, e.g., KSPCreate().
8386 
8387    Level: developer
8388 
8389    Concepts: matrices^triangular solves
8390 
8391 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8392 @*/
8393 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8394 {
8395   PetscErrorCode ierr;
8396 
8397   PetscFunctionBegin;
8398   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8399   PetscValidType(mat,1);
8400   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8401   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8402   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8403 
8404   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8405   MatCheckPreallocated(mat,1);
8406   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8407   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8408   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8409   PetscFunctionReturn(0);
8410 }
8411 
8412 /*@
8413    MatIsSymmetric - Test whether a matrix is symmetric
8414 
8415    Collective on Mat
8416 
8417    Input Parameter:
8418 +  A - the matrix to test
8419 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8420 
8421    Output Parameters:
8422 .  flg - the result
8423 
8424    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8425 
8426    Level: intermediate
8427 
8428    Concepts: matrix^symmetry
8429 
8430 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8431 @*/
8432 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8433 {
8434   PetscErrorCode ierr;
8435 
8436   PetscFunctionBegin;
8437   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8438   PetscValidPointer(flg,2);
8439 
8440   if (!A->symmetric_set) {
8441     if (!A->ops->issymmetric) {
8442       MatType mattype;
8443       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8444       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8445     }
8446     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8447     if (!tol) {
8448       A->symmetric_set = PETSC_TRUE;
8449       A->symmetric     = *flg;
8450       if (A->symmetric) {
8451         A->structurally_symmetric_set = PETSC_TRUE;
8452         A->structurally_symmetric     = PETSC_TRUE;
8453       }
8454     }
8455   } else if (A->symmetric) {
8456     *flg = PETSC_TRUE;
8457   } else if (!tol) {
8458     *flg = PETSC_FALSE;
8459   } else {
8460     if (!A->ops->issymmetric) {
8461       MatType mattype;
8462       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8463       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8464     }
8465     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8466   }
8467   PetscFunctionReturn(0);
8468 }
8469 
8470 /*@
8471    MatIsHermitian - Test whether a matrix is Hermitian
8472 
8473    Collective on Mat
8474 
8475    Input Parameter:
8476 +  A - the matrix to test
8477 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8478 
8479    Output Parameters:
8480 .  flg - the result
8481 
8482    Level: intermediate
8483 
8484    Concepts: matrix^symmetry
8485 
8486 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8487           MatIsSymmetricKnown(), MatIsSymmetric()
8488 @*/
8489 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8490 {
8491   PetscErrorCode ierr;
8492 
8493   PetscFunctionBegin;
8494   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8495   PetscValidPointer(flg,2);
8496 
8497   if (!A->hermitian_set) {
8498     if (!A->ops->ishermitian) {
8499       MatType mattype;
8500       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8501       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8502     }
8503     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8504     if (!tol) {
8505       A->hermitian_set = PETSC_TRUE;
8506       A->hermitian     = *flg;
8507       if (A->hermitian) {
8508         A->structurally_symmetric_set = PETSC_TRUE;
8509         A->structurally_symmetric     = PETSC_TRUE;
8510       }
8511     }
8512   } else if (A->hermitian) {
8513     *flg = PETSC_TRUE;
8514   } else if (!tol) {
8515     *flg = PETSC_FALSE;
8516   } else {
8517     if (!A->ops->ishermitian) {
8518       MatType mattype;
8519       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8520       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8521     }
8522     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8523   }
8524   PetscFunctionReturn(0);
8525 }
8526 
8527 /*@
8528    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8529 
8530    Not Collective
8531 
8532    Input Parameter:
8533 .  A - the matrix to check
8534 
8535    Output Parameters:
8536 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8537 -  flg - the result
8538 
8539    Level: advanced
8540 
8541    Concepts: matrix^symmetry
8542 
8543    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8544          if you want it explicitly checked
8545 
8546 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8547 @*/
8548 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8549 {
8550   PetscFunctionBegin;
8551   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8552   PetscValidPointer(set,2);
8553   PetscValidPointer(flg,3);
8554   if (A->symmetric_set) {
8555     *set = PETSC_TRUE;
8556     *flg = A->symmetric;
8557   } else {
8558     *set = PETSC_FALSE;
8559   }
8560   PetscFunctionReturn(0);
8561 }
8562 
8563 /*@
8564    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8565 
8566    Not Collective
8567 
8568    Input Parameter:
8569 .  A - the matrix to check
8570 
8571    Output Parameters:
8572 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8573 -  flg - the result
8574 
8575    Level: advanced
8576 
8577    Concepts: matrix^symmetry
8578 
8579    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8580          if you want it explicitly checked
8581 
8582 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8583 @*/
8584 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8585 {
8586   PetscFunctionBegin;
8587   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8588   PetscValidPointer(set,2);
8589   PetscValidPointer(flg,3);
8590   if (A->hermitian_set) {
8591     *set = PETSC_TRUE;
8592     *flg = A->hermitian;
8593   } else {
8594     *set = PETSC_FALSE;
8595   }
8596   PetscFunctionReturn(0);
8597 }
8598 
8599 /*@
8600    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8601 
8602    Collective on Mat
8603 
8604    Input Parameter:
8605 .  A - the matrix to test
8606 
8607    Output Parameters:
8608 .  flg - the result
8609 
8610    Level: intermediate
8611 
8612    Concepts: matrix^symmetry
8613 
8614 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8615 @*/
8616 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8617 {
8618   PetscErrorCode ierr;
8619 
8620   PetscFunctionBegin;
8621   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8622   PetscValidPointer(flg,2);
8623   if (!A->structurally_symmetric_set) {
8624     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8625     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8626 
8627     A->structurally_symmetric_set = PETSC_TRUE;
8628   }
8629   *flg = A->structurally_symmetric;
8630   PetscFunctionReturn(0);
8631 }
8632 
8633 /*@
8634    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8635        to be communicated to other processors during the MatAssemblyBegin/End() process
8636 
8637     Not collective
8638 
8639    Input Parameter:
8640 .   vec - the vector
8641 
8642    Output Parameters:
8643 +   nstash   - the size of the stash
8644 .   reallocs - the number of additional mallocs incurred.
8645 .   bnstash   - the size of the block stash
8646 -   breallocs - the number of additional mallocs incurred.in the block stash
8647 
8648    Level: advanced
8649 
8650 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8651 
8652 @*/
8653 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8654 {
8655   PetscErrorCode ierr;
8656 
8657   PetscFunctionBegin;
8658   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8659   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8660   PetscFunctionReturn(0);
8661 }
8662 
8663 /*@C
8664    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8665      parallel layout
8666 
8667    Collective on Mat
8668 
8669    Input Parameter:
8670 .  mat - the matrix
8671 
8672    Output Parameter:
8673 +   right - (optional) vector that the matrix can be multiplied against
8674 -   left - (optional) vector that the matrix vector product can be stored in
8675 
8676    Notes:
8677     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().
8678 
8679   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8680 
8681   Level: advanced
8682 
8683 .seealso: MatCreate(), VecDestroy()
8684 @*/
8685 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8686 {
8687   PetscErrorCode ierr;
8688 
8689   PetscFunctionBegin;
8690   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8691   PetscValidType(mat,1);
8692   if (mat->ops->getvecs) {
8693     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8694   } else {
8695     PetscInt rbs,cbs;
8696     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8697     if (right) {
8698       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8699       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8700       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8701       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8702       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8703       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8704     }
8705     if (left) {
8706       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8707       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8708       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8709       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8710       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8711       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8712     }
8713   }
8714   PetscFunctionReturn(0);
8715 }
8716 
8717 /*@C
8718    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8719      with default values.
8720 
8721    Not Collective
8722 
8723    Input Parameters:
8724 .    info - the MatFactorInfo data structure
8725 
8726 
8727    Notes: The solvers are generally used through the KSP and PC objects, for example
8728           PCLU, PCILU, PCCHOLESKY, PCICC
8729 
8730    Level: developer
8731 
8732 .seealso: MatFactorInfo
8733 
8734     Developer Note: fortran interface is not autogenerated as the f90
8735     interface defintion cannot be generated correctly [due to MatFactorInfo]
8736 
8737 @*/
8738 
8739 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8740 {
8741   PetscErrorCode ierr;
8742 
8743   PetscFunctionBegin;
8744   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8745   PetscFunctionReturn(0);
8746 }
8747 
8748 /*@
8749    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8750 
8751    Collective on Mat
8752 
8753    Input Parameters:
8754 +  mat - the factored matrix
8755 -  is - the index set defining the Schur indices (0-based)
8756 
8757    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8758 
8759    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8760 
8761    Level: developer
8762 
8763    Concepts:
8764 
8765 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8766           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8767 
8768 @*/
8769 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8770 {
8771   PetscErrorCode ierr,(*f)(Mat,IS);
8772 
8773   PetscFunctionBegin;
8774   PetscValidType(mat,1);
8775   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8776   PetscValidType(is,2);
8777   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8778   PetscCheckSameComm(mat,1,is,2);
8779   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8780   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8781   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");
8782   if (mat->schur) {
8783     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8784   }
8785   ierr = (*f)(mat,is);CHKERRQ(ierr);
8786   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8787   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8788   PetscFunctionReturn(0);
8789 }
8790 
8791 /*@
8792   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8793 
8794    Logically Collective on Mat
8795 
8796    Input Parameters:
8797 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8798 .  S - location where to return the Schur complement, can be NULL
8799 -  status - the status of the Schur complement matrix, can be NULL
8800 
8801    Notes:
8802    You must call MatFactorSetSchurIS() before calling this routine.
8803 
8804    The routine provides a copy of the Schur matrix stored within the solver data structures.
8805    The caller must destroy the object when it is no longer needed.
8806    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8807 
8808    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)
8809 
8810    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
8811    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8812 
8813    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8814 
8815    Level: advanced
8816 
8817    References:
8818 
8819 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8820 @*/
8821 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8822 {
8823   PetscErrorCode ierr;
8824 
8825   PetscFunctionBegin;
8826   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8827   if (S) PetscValidPointer(S,2);
8828   if (status) PetscValidPointer(status,3);
8829   if (S) {
8830     PetscErrorCode (*f)(Mat,Mat*);
8831 
8832     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8833     if (f) {
8834       ierr = (*f)(F,S);CHKERRQ(ierr);
8835     } else {
8836       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8837     }
8838   }
8839   if (status) *status = F->schur_status;
8840   PetscFunctionReturn(0);
8841 }
8842 
8843 /*@
8844   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8845 
8846    Logically Collective on Mat
8847 
8848    Input Parameters:
8849 +  F - the factored matrix obtained by calling MatGetFactor()
8850 .  *S - location where to return the Schur complement, can be NULL
8851 -  status - the status of the Schur complement matrix, can be NULL
8852 
8853    Notes:
8854    You must call MatFactorSetSchurIS() before calling this routine.
8855 
8856    Schur complement mode is currently implemented for sequential matrices.
8857    The routine returns a the Schur Complement stored within the data strutures of the solver.
8858    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8859    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8860 
8861    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8862 
8863    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8864 
8865    Level: advanced
8866 
8867    References:
8868 
8869 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8870 @*/
8871 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8872 {
8873   PetscFunctionBegin;
8874   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8875   if (S) PetscValidPointer(S,2);
8876   if (status) PetscValidPointer(status,3);
8877   if (S) *S = F->schur;
8878   if (status) *status = F->schur_status;
8879   PetscFunctionReturn(0);
8880 }
8881 
8882 /*@
8883   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8884 
8885    Logically Collective on Mat
8886 
8887    Input Parameters:
8888 +  F - the factored matrix obtained by calling MatGetFactor()
8889 .  *S - location where the Schur complement is stored
8890 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8891 
8892    Notes:
8893 
8894    Level: advanced
8895 
8896    References:
8897 
8898 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8899 @*/
8900 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8901 {
8902   PetscErrorCode ierr;
8903 
8904   PetscFunctionBegin;
8905   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8906   if (S) {
8907     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8908     *S = NULL;
8909   }
8910   F->schur_status = status;
8911   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8912   PetscFunctionReturn(0);
8913 }
8914 
8915 /*@
8916   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8917 
8918    Logically Collective on Mat
8919 
8920    Input Parameters:
8921 +  F - the factored matrix obtained by calling MatGetFactor()
8922 .  rhs - location where the right hand side of the Schur complement system is stored
8923 -  sol - location where the solution of the Schur complement system has to be returned
8924 
8925    Notes:
8926    The sizes of the vectors should match the size of the Schur complement
8927 
8928    Must be called after MatFactorSetSchurIS()
8929 
8930    Level: advanced
8931 
8932    References:
8933 
8934 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8935 @*/
8936 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8937 {
8938   PetscErrorCode ierr;
8939 
8940   PetscFunctionBegin;
8941   PetscValidType(F,1);
8942   PetscValidType(rhs,2);
8943   PetscValidType(sol,3);
8944   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8945   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8946   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8947   PetscCheckSameComm(F,1,rhs,2);
8948   PetscCheckSameComm(F,1,sol,3);
8949   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8950   switch (F->schur_status) {
8951   case MAT_FACTOR_SCHUR_FACTORED:
8952     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8953     break;
8954   case MAT_FACTOR_SCHUR_INVERTED:
8955     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8956     break;
8957   default:
8958     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8959     break;
8960   }
8961   PetscFunctionReturn(0);
8962 }
8963 
8964 /*@
8965   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8966 
8967    Logically Collective on Mat
8968 
8969    Input Parameters:
8970 +  F - the factored matrix obtained by calling MatGetFactor()
8971 .  rhs - location where the right hand side of the Schur complement system is stored
8972 -  sol - location where the solution of the Schur complement system has to be returned
8973 
8974    Notes:
8975    The sizes of the vectors should match the size of the Schur complement
8976 
8977    Must be called after MatFactorSetSchurIS()
8978 
8979    Level: advanced
8980 
8981    References:
8982 
8983 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
8984 @*/
8985 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8986 {
8987   PetscErrorCode ierr;
8988 
8989   PetscFunctionBegin;
8990   PetscValidType(F,1);
8991   PetscValidType(rhs,2);
8992   PetscValidType(sol,3);
8993   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8994   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8995   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8996   PetscCheckSameComm(F,1,rhs,2);
8997   PetscCheckSameComm(F,1,sol,3);
8998   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8999   switch (F->schur_status) {
9000   case MAT_FACTOR_SCHUR_FACTORED:
9001     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9002     break;
9003   case MAT_FACTOR_SCHUR_INVERTED:
9004     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9005     break;
9006   default:
9007     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9008     break;
9009   }
9010   PetscFunctionReturn(0);
9011 }
9012 
9013 /*@
9014   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9015 
9016    Logically Collective on Mat
9017 
9018    Input Parameters:
9019 +  F - the factored matrix obtained by calling MatGetFactor()
9020 
9021    Notes: Must be called after MatFactorSetSchurIS().
9022 
9023    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9024 
9025    Level: advanced
9026 
9027    References:
9028 
9029 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9030 @*/
9031 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9032 {
9033   PetscErrorCode ierr;
9034 
9035   PetscFunctionBegin;
9036   PetscValidType(F,1);
9037   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9038   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9039   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9040   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9041   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9042   PetscFunctionReturn(0);
9043 }
9044 
9045 /*@
9046   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9047 
9048    Logically Collective on Mat
9049 
9050    Input Parameters:
9051 +  F - the factored matrix obtained by calling MatGetFactor()
9052 
9053    Notes: Must be called after MatFactorSetSchurIS().
9054 
9055    Level: advanced
9056 
9057    References:
9058 
9059 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9060 @*/
9061 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9062 {
9063   PetscErrorCode ierr;
9064 
9065   PetscFunctionBegin;
9066   PetscValidType(F,1);
9067   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9068   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9069   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9070   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9071   PetscFunctionReturn(0);
9072 }
9073 
9074 /*@
9075    MatPtAP - Creates the matrix product C = P^T * A * P
9076 
9077    Neighbor-wise Collective on Mat
9078 
9079    Input Parameters:
9080 +  A - the matrix
9081 .  P - the projection matrix
9082 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9083 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9084           if the result is a dense matrix this is irrelevent
9085 
9086    Output Parameters:
9087 .  C - the product matrix
9088 
9089    Notes:
9090    C will be created and must be destroyed by the user with MatDestroy().
9091 
9092    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9093    which inherit from AIJ.
9094 
9095    Level: intermediate
9096 
9097 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9098 @*/
9099 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9100 {
9101   PetscErrorCode ierr;
9102   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9103   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9104   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9105 
9106   PetscFunctionBegin;
9107   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9108   PetscValidType(A,1);
9109   MatCheckPreallocated(A,1);
9110   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9111   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9112   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9113   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9114   PetscValidType(P,2);
9115   MatCheckPreallocated(P,2);
9116   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9117   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9118 
9119   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);
9120   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);
9121   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9122   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9123 
9124   if (scall == MAT_REUSE_MATRIX) {
9125     PetscValidPointer(*C,5);
9126     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9127 
9128     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9129     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9130     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9131     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9132     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9133     PetscFunctionReturn(0);
9134   }
9135 
9136   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9137   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9138 
9139   fA = A->ops->ptap;
9140   fP = P->ops->ptap;
9141   if (fP == fA) {
9142     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9143     ptap = fA;
9144   } else {
9145     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9146     char ptapname[256];
9147     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9148     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9149     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9150     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9151     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9152     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9153     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);
9154   }
9155 
9156   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9157   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9158   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9159   PetscFunctionReturn(0);
9160 }
9161 
9162 /*@
9163    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9164 
9165    Neighbor-wise Collective on Mat
9166 
9167    Input Parameters:
9168 +  A - the matrix
9169 -  P - the projection matrix
9170 
9171    Output Parameters:
9172 .  C - the product matrix
9173 
9174    Notes:
9175    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9176    the user using MatDeatroy().
9177 
9178    This routine is currently only implemented for pairs of AIJ matrices and classes
9179    which inherit from AIJ.  C will be of type MATAIJ.
9180 
9181    Level: intermediate
9182 
9183 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9184 @*/
9185 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9186 {
9187   PetscErrorCode ierr;
9188 
9189   PetscFunctionBegin;
9190   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9191   PetscValidType(A,1);
9192   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9193   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9194   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9195   PetscValidType(P,2);
9196   MatCheckPreallocated(P,2);
9197   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9198   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9199   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9200   PetscValidType(C,3);
9201   MatCheckPreallocated(C,3);
9202   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9203   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);
9204   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);
9205   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);
9206   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);
9207   MatCheckPreallocated(A,1);
9208 
9209   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9210   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9211   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9212   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9213   PetscFunctionReturn(0);
9214 }
9215 
9216 /*@
9217    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9218 
9219    Neighbor-wise Collective on Mat
9220 
9221    Input Parameters:
9222 +  A - the matrix
9223 -  P - the projection matrix
9224 
9225    Output Parameters:
9226 .  C - the (i,j) structure of the product matrix
9227 
9228    Notes:
9229    C will be created and must be destroyed by the user with MatDestroy().
9230 
9231    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9232    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9233    this (i,j) structure by calling MatPtAPNumeric().
9234 
9235    Level: intermediate
9236 
9237 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9238 @*/
9239 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9240 {
9241   PetscErrorCode ierr;
9242 
9243   PetscFunctionBegin;
9244   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9245   PetscValidType(A,1);
9246   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9247   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9248   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9249   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9250   PetscValidType(P,2);
9251   MatCheckPreallocated(P,2);
9252   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9253   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9254   PetscValidPointer(C,3);
9255 
9256   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);
9257   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);
9258   MatCheckPreallocated(A,1);
9259 
9260   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9261   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9262   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9263   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9264 
9265   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9266   PetscFunctionReturn(0);
9267 }
9268 
9269 /*@
9270    MatRARt - Creates the matrix product C = R * A * R^T
9271 
9272    Neighbor-wise Collective on Mat
9273 
9274    Input Parameters:
9275 +  A - the matrix
9276 .  R - the projection matrix
9277 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9278 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9279           if the result is a dense matrix this is irrelevent
9280 
9281    Output Parameters:
9282 .  C - the product matrix
9283 
9284    Notes:
9285    C will be created and must be destroyed by the user with MatDestroy().
9286 
9287    This routine is currently only implemented for pairs of AIJ matrices and classes
9288    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9289    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9290    We recommend using MatPtAP().
9291 
9292    Level: intermediate
9293 
9294 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9295 @*/
9296 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9297 {
9298   PetscErrorCode ierr;
9299 
9300   PetscFunctionBegin;
9301   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9302   PetscValidType(A,1);
9303   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9304   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9305   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9306   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9307   PetscValidType(R,2);
9308   MatCheckPreallocated(R,2);
9309   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9310   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9311   PetscValidPointer(C,3);
9312   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);
9313 
9314   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9315   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9316   MatCheckPreallocated(A,1);
9317 
9318   if (!A->ops->rart) {
9319     Mat Rt;
9320     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9321     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9322     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9323     PetscFunctionReturn(0);
9324   }
9325   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9326   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9327   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9328   PetscFunctionReturn(0);
9329 }
9330 
9331 /*@
9332    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9333 
9334    Neighbor-wise Collective on Mat
9335 
9336    Input Parameters:
9337 +  A - the matrix
9338 -  R - the projection matrix
9339 
9340    Output Parameters:
9341 .  C - the product matrix
9342 
9343    Notes:
9344    C must have been created by calling MatRARtSymbolic and must be destroyed by
9345    the user using MatDestroy().
9346 
9347    This routine is currently only implemented for pairs of AIJ matrices and classes
9348    which inherit from AIJ.  C will be of type MATAIJ.
9349 
9350    Level: intermediate
9351 
9352 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9353 @*/
9354 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9355 {
9356   PetscErrorCode ierr;
9357 
9358   PetscFunctionBegin;
9359   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9360   PetscValidType(A,1);
9361   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9362   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9363   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9364   PetscValidType(R,2);
9365   MatCheckPreallocated(R,2);
9366   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9367   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9368   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9369   PetscValidType(C,3);
9370   MatCheckPreallocated(C,3);
9371   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9372   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);
9373   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);
9374   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);
9375   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);
9376   MatCheckPreallocated(A,1);
9377 
9378   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9379   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9380   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9381   PetscFunctionReturn(0);
9382 }
9383 
9384 /*@
9385    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9386 
9387    Neighbor-wise Collective on Mat
9388 
9389    Input Parameters:
9390 +  A - the matrix
9391 -  R - the projection matrix
9392 
9393    Output Parameters:
9394 .  C - the (i,j) structure of the product matrix
9395 
9396    Notes:
9397    C will be created and must be destroyed by the user with MatDestroy().
9398 
9399    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9400    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9401    this (i,j) structure by calling MatRARtNumeric().
9402 
9403    Level: intermediate
9404 
9405 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9406 @*/
9407 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9408 {
9409   PetscErrorCode ierr;
9410 
9411   PetscFunctionBegin;
9412   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9413   PetscValidType(A,1);
9414   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9415   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9416   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9417   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9418   PetscValidType(R,2);
9419   MatCheckPreallocated(R,2);
9420   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9421   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9422   PetscValidPointer(C,3);
9423 
9424   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);
9425   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);
9426   MatCheckPreallocated(A,1);
9427   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9428   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9429   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9430 
9431   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9432   PetscFunctionReturn(0);
9433 }
9434 
9435 /*@
9436    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9437 
9438    Neighbor-wise Collective on Mat
9439 
9440    Input Parameters:
9441 +  A - the left matrix
9442 .  B - the right matrix
9443 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9444 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9445           if the result is a dense matrix this is irrelevent
9446 
9447    Output Parameters:
9448 .  C - the product matrix
9449 
9450    Notes:
9451    Unless scall is MAT_REUSE_MATRIX C will be created.
9452 
9453    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
9454    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9455 
9456    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9457    actually needed.
9458 
9459    If you have many matrices with the same non-zero structure to multiply, you
9460    should either
9461 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9462 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9463    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
9464    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9465 
9466    Level: intermediate
9467 
9468 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9469 @*/
9470 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9471 {
9472   PetscErrorCode ierr;
9473   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9474   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9475   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9476 
9477   PetscFunctionBegin;
9478   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9479   PetscValidType(A,1);
9480   MatCheckPreallocated(A,1);
9481   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9482   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9483   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9484   PetscValidType(B,2);
9485   MatCheckPreallocated(B,2);
9486   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9487   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9488   PetscValidPointer(C,3);
9489   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9490   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);
9491   if (scall == MAT_REUSE_MATRIX) {
9492     PetscValidPointer(*C,5);
9493     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9494     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9495     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9496     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9497     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9498     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9499     PetscFunctionReturn(0);
9500   }
9501   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9502   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9503 
9504   fA = A->ops->matmult;
9505   fB = B->ops->matmult;
9506   if (fB == fA) {
9507     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9508     mult = fB;
9509   } else {
9510     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9511     char multname[256];
9512     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9513     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9514     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9515     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9516     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9517     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9518     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);
9519   }
9520   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9521   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9522   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9523   PetscFunctionReturn(0);
9524 }
9525 
9526 /*@
9527    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9528    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9529 
9530    Neighbor-wise Collective on Mat
9531 
9532    Input Parameters:
9533 +  A - the left matrix
9534 .  B - the right matrix
9535 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9536       if C is a dense matrix this is irrelevent
9537 
9538    Output Parameters:
9539 .  C - the product matrix
9540 
9541    Notes:
9542    Unless scall is MAT_REUSE_MATRIX C will be created.
9543 
9544    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9545    actually needed.
9546 
9547    This routine is currently implemented for
9548     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9549     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9550     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9551 
9552    Level: intermediate
9553 
9554    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9555      We should incorporate them into PETSc.
9556 
9557 .seealso: MatMatMult(), MatMatMultNumeric()
9558 @*/
9559 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9560 {
9561   PetscErrorCode ierr;
9562   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9563   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9564   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9565 
9566   PetscFunctionBegin;
9567   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9568   PetscValidType(A,1);
9569   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9570   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9571 
9572   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9573   PetscValidType(B,2);
9574   MatCheckPreallocated(B,2);
9575   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9576   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9577   PetscValidPointer(C,3);
9578 
9579   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);
9580   if (fill == PETSC_DEFAULT) fill = 2.0;
9581   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9582   MatCheckPreallocated(A,1);
9583 
9584   Asymbolic = A->ops->matmultsymbolic;
9585   Bsymbolic = B->ops->matmultsymbolic;
9586   if (Asymbolic == Bsymbolic) {
9587     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9588     symbolic = Bsymbolic;
9589   } else { /* dispatch based on the type of A and B */
9590     char symbolicname[256];
9591     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9592     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9593     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9594     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9595     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9596     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9597     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);
9598   }
9599   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9600   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9601   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9602   PetscFunctionReturn(0);
9603 }
9604 
9605 /*@
9606    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9607    Call this routine after first calling MatMatMultSymbolic().
9608 
9609    Neighbor-wise Collective on Mat
9610 
9611    Input Parameters:
9612 +  A - the left matrix
9613 -  B - the right matrix
9614 
9615    Output Parameters:
9616 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9617 
9618    Notes:
9619    C must have been created with MatMatMultSymbolic().
9620 
9621    This routine is currently implemented for
9622     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9623     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9624     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9625 
9626    Level: intermediate
9627 
9628 .seealso: MatMatMult(), MatMatMultSymbolic()
9629 @*/
9630 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9631 {
9632   PetscErrorCode ierr;
9633 
9634   PetscFunctionBegin;
9635   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9636   PetscFunctionReturn(0);
9637 }
9638 
9639 /*@
9640    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9641 
9642    Neighbor-wise Collective on Mat
9643 
9644    Input Parameters:
9645 +  A - the left matrix
9646 .  B - the right matrix
9647 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9648 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9649 
9650    Output Parameters:
9651 .  C - the product matrix
9652 
9653    Notes:
9654    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9655 
9656    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9657 
9658   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9659    actually needed.
9660 
9661    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9662 
9663    Level: intermediate
9664 
9665 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9666 @*/
9667 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9668 {
9669   PetscErrorCode ierr;
9670   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9671   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9672 
9673   PetscFunctionBegin;
9674   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9675   PetscValidType(A,1);
9676   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9677   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9678   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9679   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9680   PetscValidType(B,2);
9681   MatCheckPreallocated(B,2);
9682   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9683   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9684   PetscValidPointer(C,3);
9685   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);
9686   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9687   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9688   MatCheckPreallocated(A,1);
9689 
9690   fA = A->ops->mattransposemult;
9691   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9692   fB = B->ops->mattransposemult;
9693   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9694   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);
9695 
9696   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9697   if (scall == MAT_INITIAL_MATRIX) {
9698     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9699     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9700     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9701   }
9702   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9703   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9704   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9705   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9706   PetscFunctionReturn(0);
9707 }
9708 
9709 /*@
9710    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9711 
9712    Neighbor-wise Collective on Mat
9713 
9714    Input Parameters:
9715 +  A - the left matrix
9716 .  B - the right matrix
9717 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9718 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9719 
9720    Output Parameters:
9721 .  C - the product matrix
9722 
9723    Notes:
9724    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9725 
9726    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9727 
9728   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9729    actually needed.
9730 
9731    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9732    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9733 
9734    Level: intermediate
9735 
9736 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9737 @*/
9738 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9739 {
9740   PetscErrorCode ierr;
9741   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9742   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9743   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9744 
9745   PetscFunctionBegin;
9746   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9747   PetscValidType(A,1);
9748   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9749   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9750   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9751   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9752   PetscValidType(B,2);
9753   MatCheckPreallocated(B,2);
9754   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9755   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9756   PetscValidPointer(C,3);
9757   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);
9758   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9759   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9760   MatCheckPreallocated(A,1);
9761 
9762   fA = A->ops->transposematmult;
9763   fB = B->ops->transposematmult;
9764   if (fB==fA) {
9765     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9766     transposematmult = fA;
9767   } else {
9768     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9769     char multname[256];
9770     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9771     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9772     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9773     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9774     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9775     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9776     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);
9777   }
9778   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9779   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9780   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9781   PetscFunctionReturn(0);
9782 }
9783 
9784 /*@
9785    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9786 
9787    Neighbor-wise Collective on Mat
9788 
9789    Input Parameters:
9790 +  A - the left matrix
9791 .  B - the middle matrix
9792 .  C - the right matrix
9793 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9794 -  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
9795           if the result is a dense matrix this is irrelevent
9796 
9797    Output Parameters:
9798 .  D - the product matrix
9799 
9800    Notes:
9801    Unless scall is MAT_REUSE_MATRIX D will be created.
9802 
9803    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9804 
9805    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9806    actually needed.
9807 
9808    If you have many matrices with the same non-zero structure to multiply, you
9809    should use MAT_REUSE_MATRIX in all calls but the first or
9810 
9811    Level: intermediate
9812 
9813 .seealso: MatMatMult, MatPtAP()
9814 @*/
9815 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9816 {
9817   PetscErrorCode ierr;
9818   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9819   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9820   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9821   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9822 
9823   PetscFunctionBegin;
9824   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9825   PetscValidType(A,1);
9826   MatCheckPreallocated(A,1);
9827   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9828   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9829   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9830   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9831   PetscValidType(B,2);
9832   MatCheckPreallocated(B,2);
9833   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9834   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9836   PetscValidPointer(C,3);
9837   MatCheckPreallocated(C,3);
9838   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9839   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9840   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);
9841   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);
9842   if (scall == MAT_REUSE_MATRIX) {
9843     PetscValidPointer(*D,6);
9844     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9845     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9846     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9847     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9848     PetscFunctionReturn(0);
9849   }
9850   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9851   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9852 
9853   fA = A->ops->matmatmult;
9854   fB = B->ops->matmatmult;
9855   fC = C->ops->matmatmult;
9856   if (fA == fB && fA == fC) {
9857     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9858     mult = fA;
9859   } else {
9860     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9861     char multname[256];
9862     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
9863     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9864     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9865     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9866     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9867     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
9868     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
9869     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9870     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);
9871   }
9872   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9873   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9874   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9875   PetscFunctionReturn(0);
9876 }
9877 
9878 /*@
9879    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9880 
9881    Collective on Mat
9882 
9883    Input Parameters:
9884 +  mat - the matrix
9885 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9886 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9887 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9888 
9889    Output Parameter:
9890 .  matredundant - redundant matrix
9891 
9892    Notes:
9893    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9894    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9895 
9896    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9897    calling it.
9898 
9899    Level: advanced
9900 
9901    Concepts: subcommunicator
9902    Concepts: duplicate matrix
9903 
9904 .seealso: MatDestroy()
9905 @*/
9906 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9907 {
9908   PetscErrorCode ierr;
9909   MPI_Comm       comm;
9910   PetscMPIInt    size;
9911   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9912   Mat_Redundant  *redund=NULL;
9913   PetscSubcomm   psubcomm=NULL;
9914   MPI_Comm       subcomm_in=subcomm;
9915   Mat            *matseq;
9916   IS             isrow,iscol;
9917   PetscBool      newsubcomm=PETSC_FALSE;
9918 
9919   PetscFunctionBegin;
9920   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9921   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9922     PetscValidPointer(*matredundant,5);
9923     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9924   }
9925 
9926   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9927   if (size == 1 || nsubcomm == 1) {
9928     if (reuse == MAT_INITIAL_MATRIX) {
9929       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9930     } else {
9931       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");
9932       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9933     }
9934     PetscFunctionReturn(0);
9935   }
9936 
9937   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9938   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9939   MatCheckPreallocated(mat,1);
9940 
9941   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9942   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9943     /* create psubcomm, then get subcomm */
9944     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9945     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9946     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9947 
9948     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9949     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9950     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9951     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9952     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9953     newsubcomm = PETSC_TRUE;
9954     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9955   }
9956 
9957   /* get isrow, iscol and a local sequential matrix matseq[0] */
9958   if (reuse == MAT_INITIAL_MATRIX) {
9959     mloc_sub = PETSC_DECIDE;
9960     nloc_sub = PETSC_DECIDE;
9961     if (bs < 1) {
9962       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9963       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9964     } else {
9965       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9966       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
9967     }
9968     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9969     rstart = rend - mloc_sub;
9970     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9971     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9972   } else { /* reuse == MAT_REUSE_MATRIX */
9973     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");
9974     /* retrieve subcomm */
9975     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9976     redund = (*matredundant)->redundant;
9977     isrow  = redund->isrow;
9978     iscol  = redund->iscol;
9979     matseq = redund->matseq;
9980   }
9981   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9982 
9983   /* get matredundant over subcomm */
9984   if (reuse == MAT_INITIAL_MATRIX) {
9985     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
9986 
9987     /* create a supporting struct and attach it to C for reuse */
9988     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9989     (*matredundant)->redundant = redund;
9990     redund->isrow              = isrow;
9991     redund->iscol              = iscol;
9992     redund->matseq             = matseq;
9993     if (newsubcomm) {
9994       redund->subcomm          = subcomm;
9995     } else {
9996       redund->subcomm          = MPI_COMM_NULL;
9997     }
9998   } else {
9999     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10000   }
10001   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10002   PetscFunctionReturn(0);
10003 }
10004 
10005 /*@C
10006    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10007    a given 'mat' object. Each submatrix can span multiple procs.
10008 
10009    Collective on Mat
10010 
10011    Input Parameters:
10012 +  mat - the matrix
10013 .  subcomm - the subcommunicator obtained by com_split(comm)
10014 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10015 
10016    Output Parameter:
10017 .  subMat - 'parallel submatrices each spans a given subcomm
10018 
10019   Notes:
10020   The submatrix partition across processors is dictated by 'subComm' a
10021   communicator obtained by com_split(comm). The comm_split
10022   is not restriced to be grouped with consecutive original ranks.
10023 
10024   Due the comm_split() usage, the parallel layout of the submatrices
10025   map directly to the layout of the original matrix [wrt the local
10026   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10027   into the 'DiagonalMat' of the subMat, hence it is used directly from
10028   the subMat. However the offDiagMat looses some columns - and this is
10029   reconstructed with MatSetValues()
10030 
10031   Level: advanced
10032 
10033   Concepts: subcommunicator
10034   Concepts: submatrices
10035 
10036 .seealso: MatCreateSubMatrices()
10037 @*/
10038 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10039 {
10040   PetscErrorCode ierr;
10041   PetscMPIInt    commsize,subCommSize;
10042 
10043   PetscFunctionBegin;
10044   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10045   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10046   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10047 
10048   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");
10049   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10050   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10051   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10052   PetscFunctionReturn(0);
10053 }
10054 
10055 /*@
10056    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10057 
10058    Not Collective
10059 
10060    Input Arguments:
10061    mat - matrix to extract local submatrix from
10062    isrow - local row indices for submatrix
10063    iscol - local column indices for submatrix
10064 
10065    Output Arguments:
10066    submat - the submatrix
10067 
10068    Level: intermediate
10069 
10070    Notes:
10071    The submat should be returned with MatRestoreLocalSubMatrix().
10072 
10073    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10074    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10075 
10076    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10077    MatSetValuesBlockedLocal() will also be implemented.
10078 
10079    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10080    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10081 
10082 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10083 @*/
10084 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10085 {
10086   PetscErrorCode ierr;
10087 
10088   PetscFunctionBegin;
10089   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10090   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10091   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10092   PetscCheckSameComm(isrow,2,iscol,3);
10093   PetscValidPointer(submat,4);
10094   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10095 
10096   if (mat->ops->getlocalsubmatrix) {
10097     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10098   } else {
10099     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10100   }
10101   PetscFunctionReturn(0);
10102 }
10103 
10104 /*@
10105    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10106 
10107    Not Collective
10108 
10109    Input Arguments:
10110    mat - matrix to extract local submatrix from
10111    isrow - local row indices for submatrix
10112    iscol - local column indices for submatrix
10113    submat - the submatrix
10114 
10115    Level: intermediate
10116 
10117 .seealso: MatGetLocalSubMatrix()
10118 @*/
10119 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10120 {
10121   PetscErrorCode ierr;
10122 
10123   PetscFunctionBegin;
10124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10125   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10126   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10127   PetscCheckSameComm(isrow,2,iscol,3);
10128   PetscValidPointer(submat,4);
10129   if (*submat) {
10130     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10131   }
10132 
10133   if (mat->ops->restorelocalsubmatrix) {
10134     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10135   } else {
10136     ierr = MatDestroy(submat);CHKERRQ(ierr);
10137   }
10138   *submat = NULL;
10139   PetscFunctionReturn(0);
10140 }
10141 
10142 /* --------------------------------------------------------*/
10143 /*@
10144    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10145 
10146    Collective on Mat
10147 
10148    Input Parameter:
10149 .  mat - the matrix
10150 
10151    Output Parameter:
10152 .  is - if any rows have zero diagonals this contains the list of them
10153 
10154    Level: developer
10155 
10156    Concepts: matrix-vector product
10157 
10158 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10159 @*/
10160 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10161 {
10162   PetscErrorCode ierr;
10163 
10164   PetscFunctionBegin;
10165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10166   PetscValidType(mat,1);
10167   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10168   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10169 
10170   if (!mat->ops->findzerodiagonals) {
10171     Vec                diag;
10172     const PetscScalar *a;
10173     PetscInt          *rows;
10174     PetscInt           rStart, rEnd, r, nrow = 0;
10175 
10176     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10177     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10178     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10179     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10180     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10181     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10182     nrow = 0;
10183     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10184     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10185     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10186     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10187   } else {
10188     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10189   }
10190   PetscFunctionReturn(0);
10191 }
10192 
10193 /*@
10194    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10195 
10196    Collective on Mat
10197 
10198    Input Parameter:
10199 .  mat - the matrix
10200 
10201    Output Parameter:
10202 .  is - contains the list of rows with off block diagonal entries
10203 
10204    Level: developer
10205 
10206    Concepts: matrix-vector product
10207 
10208 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10209 @*/
10210 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10211 {
10212   PetscErrorCode ierr;
10213 
10214   PetscFunctionBegin;
10215   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10216   PetscValidType(mat,1);
10217   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10218   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10219 
10220   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10221   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10222   PetscFunctionReturn(0);
10223 }
10224 
10225 /*@C
10226   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10227 
10228   Collective on Mat
10229 
10230   Input Parameters:
10231 . mat - the matrix
10232 
10233   Output Parameters:
10234 . values - the block inverses in column major order (FORTRAN-like)
10235 
10236    Note:
10237    This routine is not available from Fortran.
10238 
10239   Level: advanced
10240 
10241 .seealso: MatInvertBockDiagonalMat
10242 @*/
10243 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10244 {
10245   PetscErrorCode ierr;
10246 
10247   PetscFunctionBegin;
10248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10249   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10250   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10251   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10252   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10253   PetscFunctionReturn(0);
10254 }
10255 
10256 /*@
10257   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10258 
10259   Collective on Mat
10260 
10261   Input Parameters:
10262 . A - the matrix
10263 
10264   Output Parameters:
10265 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10266 
10267   Level: advanced
10268 
10269 .seealso: MatInvertBockDiagonal()
10270 @*/
10271 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10272 {
10273   PetscErrorCode     ierr;
10274   const PetscScalar *vals;
10275   PetscInt          *dnnz;
10276   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10277 
10278   PetscFunctionBegin;
10279   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10280   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10281   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10282   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10283   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10284   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10285   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10286   for(j = 0; j < m/bs; j++) {
10287     dnnz[j] = 1;
10288   }
10289   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10290   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10291   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10292   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10293   for (i = rstart/bs; i < rend/bs; i++) {
10294     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10295   }
10296   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10297   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10298   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10299   PetscFunctionReturn(0);
10300 }
10301 
10302 /*@C
10303     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10304     via MatTransposeColoringCreate().
10305 
10306     Collective on MatTransposeColoring
10307 
10308     Input Parameter:
10309 .   c - coloring context
10310 
10311     Level: intermediate
10312 
10313 .seealso: MatTransposeColoringCreate()
10314 @*/
10315 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10316 {
10317   PetscErrorCode       ierr;
10318   MatTransposeColoring matcolor=*c;
10319 
10320   PetscFunctionBegin;
10321   if (!matcolor) PetscFunctionReturn(0);
10322   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10323 
10324   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10325   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10326   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10327   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10328   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10329   if (matcolor->brows>0) {
10330     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10331   }
10332   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10333   PetscFunctionReturn(0);
10334 }
10335 
10336 /*@C
10337     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10338     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10339     MatTransposeColoring to sparse B.
10340 
10341     Collective on MatTransposeColoring
10342 
10343     Input Parameters:
10344 +   B - sparse matrix B
10345 .   Btdense - symbolic dense matrix B^T
10346 -   coloring - coloring context created with MatTransposeColoringCreate()
10347 
10348     Output Parameter:
10349 .   Btdense - dense matrix B^T
10350 
10351     Level: advanced
10352 
10353      Notes: These are used internally for some implementations of MatRARt()
10354 
10355 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10356 
10357 .keywords: coloring
10358 @*/
10359 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10360 {
10361   PetscErrorCode ierr;
10362 
10363   PetscFunctionBegin;
10364   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10365   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10366   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10367 
10368   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10369   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10370   PetscFunctionReturn(0);
10371 }
10372 
10373 /*@C
10374     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10375     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10376     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10377     Csp from Cden.
10378 
10379     Collective on MatTransposeColoring
10380 
10381     Input Parameters:
10382 +   coloring - coloring context created with MatTransposeColoringCreate()
10383 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10384 
10385     Output Parameter:
10386 .   Csp - sparse matrix
10387 
10388     Level: advanced
10389 
10390      Notes: These are used internally for some implementations of MatRARt()
10391 
10392 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10393 
10394 .keywords: coloring
10395 @*/
10396 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10397 {
10398   PetscErrorCode ierr;
10399 
10400   PetscFunctionBegin;
10401   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10402   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10403   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10404 
10405   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10406   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10407   PetscFunctionReturn(0);
10408 }
10409 
10410 /*@C
10411    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10412 
10413    Collective on Mat
10414 
10415    Input Parameters:
10416 +  mat - the matrix product C
10417 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10418 
10419     Output Parameter:
10420 .   color - the new coloring context
10421 
10422     Level: intermediate
10423 
10424 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10425            MatTransColoringApplyDenToSp()
10426 @*/
10427 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10428 {
10429   MatTransposeColoring c;
10430   MPI_Comm             comm;
10431   PetscErrorCode       ierr;
10432 
10433   PetscFunctionBegin;
10434   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10435   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10436   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10437 
10438   c->ctype = iscoloring->ctype;
10439   if (mat->ops->transposecoloringcreate) {
10440     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10441   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10442 
10443   *color = c;
10444   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10445   PetscFunctionReturn(0);
10446 }
10447 
10448 /*@
10449       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10450         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10451         same, otherwise it will be larger
10452 
10453      Not Collective
10454 
10455   Input Parameter:
10456 .    A  - the matrix
10457 
10458   Output Parameter:
10459 .    state - the current state
10460 
10461   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10462          different matrices
10463 
10464   Level: intermediate
10465 
10466 @*/
10467 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10468 {
10469   PetscFunctionBegin;
10470   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10471   *state = mat->nonzerostate;
10472   PetscFunctionReturn(0);
10473 }
10474 
10475 /*@
10476       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10477                  matrices from each processor
10478 
10479     Collective on MPI_Comm
10480 
10481    Input Parameters:
10482 +    comm - the communicators the parallel matrix will live on
10483 .    seqmat - the input sequential matrices
10484 .    n - number of local columns (or PETSC_DECIDE)
10485 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10486 
10487    Output Parameter:
10488 .    mpimat - the parallel matrix generated
10489 
10490     Level: advanced
10491 
10492    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10493 
10494 @*/
10495 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10496 {
10497   PetscErrorCode ierr;
10498 
10499   PetscFunctionBegin;
10500   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10501   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");
10502 
10503   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10504   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10505   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10506   PetscFunctionReturn(0);
10507 }
10508 
10509 /*@
10510      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10511                  ranks' ownership ranges.
10512 
10513     Collective on A
10514 
10515    Input Parameters:
10516 +    A   - the matrix to create subdomains from
10517 -    N   - requested number of subdomains
10518 
10519 
10520    Output Parameters:
10521 +    n   - number of subdomains resulting on this rank
10522 -    iss - IS list with indices of subdomains on this rank
10523 
10524     Level: advanced
10525 
10526     Notes: number of subdomains must be smaller than the communicator size
10527 @*/
10528 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10529 {
10530   MPI_Comm        comm,subcomm;
10531   PetscMPIInt     size,rank,color;
10532   PetscInt        rstart,rend,k;
10533   PetscErrorCode  ierr;
10534 
10535   PetscFunctionBegin;
10536   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10537   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10538   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10539   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);
10540   *n = 1;
10541   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10542   color = rank/k;
10543   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10544   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10545   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10546   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10547   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10548   PetscFunctionReturn(0);
10549 }
10550 
10551 /*@
10552    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10553 
10554    If the interpolation and restriction operators are the same, uses MatPtAP.
10555    If they are not the same, use MatMatMatMult.
10556 
10557    Once the coarse grid problem is constructed, correct for interpolation operators
10558    that are not of full rank, which can legitimately happen in the case of non-nested
10559    geometric multigrid.
10560 
10561    Input Parameters:
10562 +  restrct - restriction operator
10563 .  dA - fine grid matrix
10564 .  interpolate - interpolation operator
10565 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10566 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10567 
10568    Output Parameters:
10569 .  A - the Galerkin coarse matrix
10570 
10571    Options Database Key:
10572 .  -pc_mg_galerkin <both,pmat,mat,none>
10573 
10574    Level: developer
10575 
10576 .keywords: MG, multigrid, Galerkin
10577 
10578 .seealso: MatPtAP(), MatMatMatMult()
10579 @*/
10580 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10581 {
10582   PetscErrorCode ierr;
10583   IS             zerorows;
10584   Vec            diag;
10585 
10586   PetscFunctionBegin;
10587   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10588   /* Construct the coarse grid matrix */
10589   if (interpolate == restrct) {
10590     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10591   } else {
10592     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10593   }
10594 
10595   /* If the interpolation matrix is not of full rank, A will have zero rows.
10596      This can legitimately happen in the case of non-nested geometric multigrid.
10597      In that event, we set the rows of the matrix to the rows of the identity,
10598      ignoring the equations (as the RHS will also be zero). */
10599 
10600   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10601 
10602   if (zerorows != NULL) { /* if there are any zero rows */
10603     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10604     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10605     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10606     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10607     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10608     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10609   }
10610   PetscFunctionReturn(0);
10611 }
10612 
10613 /*@C
10614     MatSetOperation - Allows user to set a matrix operation for any matrix type
10615 
10616    Logically Collective on Mat
10617 
10618     Input Parameters:
10619 +   mat - the matrix
10620 .   op - the name of the operation
10621 -   f - the function that provides the operation
10622 
10623    Level: developer
10624 
10625     Usage:
10626 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10627 $      ierr = MatCreateXXX(comm,...&A);
10628 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10629 
10630     Notes:
10631     See the file include/petscmat.h for a complete list of matrix
10632     operations, which all have the form MATOP_<OPERATION>, where
10633     <OPERATION> is the name (in all capital letters) of the
10634     user interface routine (e.g., MatMult() -> MATOP_MULT).
10635 
10636     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10637     sequence as the usual matrix interface routines, since they
10638     are intended to be accessed via the usual matrix interface
10639     routines, e.g.,
10640 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10641 
10642     In particular each function MUST return an error code of 0 on success and
10643     nonzero on failure.
10644 
10645     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10646 
10647 .keywords: matrix, set, operation
10648 
10649 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10650 @*/
10651 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10652 {
10653   PetscFunctionBegin;
10654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10655   if (op == MATOP_VIEW && !mat->ops->viewnative) {
10656     mat->ops->viewnative = mat->ops->view;
10657   }
10658   (((void(**)(void))mat->ops)[op]) = f;
10659   PetscFunctionReturn(0);
10660 }
10661 
10662 /*@C
10663     MatGetOperation - Gets a matrix operation for any matrix type.
10664 
10665     Not Collective
10666 
10667     Input Parameters:
10668 +   mat - the matrix
10669 -   op - the name of the operation
10670 
10671     Output Parameter:
10672 .   f - the function that provides the operation
10673 
10674     Level: developer
10675 
10676     Usage:
10677 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10678 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10679 
10680     Notes:
10681     See the file include/petscmat.h for a complete list of matrix
10682     operations, which all have the form MATOP_<OPERATION>, where
10683     <OPERATION> is the name (in all capital letters) of the
10684     user interface routine (e.g., MatMult() -> MATOP_MULT).
10685 
10686     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10687 
10688 .keywords: matrix, get, operation
10689 
10690 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10691 @*/
10692 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10693 {
10694   PetscFunctionBegin;
10695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10696   *f = (((void (**)(void))mat->ops)[op]);
10697   PetscFunctionReturn(0);
10698 }
10699 
10700 /*@
10701     MatHasOperation - Determines whether the given matrix supports the particular
10702     operation.
10703 
10704    Not Collective
10705 
10706    Input Parameters:
10707 +  mat - the matrix
10708 -  op - the operation, for example, MATOP_GET_DIAGONAL
10709 
10710    Output Parameter:
10711 .  has - either PETSC_TRUE or PETSC_FALSE
10712 
10713    Level: advanced
10714 
10715    Notes:
10716    See the file include/petscmat.h for a complete list of matrix
10717    operations, which all have the form MATOP_<OPERATION>, where
10718    <OPERATION> is the name (in all capital letters) of the
10719    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10720 
10721 .keywords: matrix, has, operation
10722 
10723 .seealso: MatCreateShell()
10724 @*/
10725 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10726 {
10727   PetscErrorCode ierr;
10728 
10729   PetscFunctionBegin;
10730   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10731   PetscValidType(mat,1);
10732   PetscValidPointer(has,3);
10733   if (mat->ops->hasoperation) {
10734     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10735   } else {
10736     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10737     else {
10738       *has = PETSC_FALSE;
10739       if (op == MATOP_CREATE_SUBMATRIX) {
10740         PetscMPIInt size;
10741 
10742         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10743         if (size == 1) {
10744           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10745         }
10746       }
10747     }
10748   }
10749   PetscFunctionReturn(0);
10750 }
10751