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