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