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