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