xref: /petsc/src/mat/interface/matrix.c (revision 60cd79ef902e2e09026d0d6629d6fe31efcd2450)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Vec
46 
47    Input Parameters:
48 +  x  - the vector
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the vector
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!rctx) {
80     MPI_Comm comm;
81     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
82     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
83     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
84     rctx = randObj;
85   }
86 
87   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
88   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
89   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90 
91   x->assembled = PETSC_TRUE;
92   ierr         = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
93   PetscFunctionReturn(0);
94 }
95 
96 /*@
97    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
98 
99    Logically Collective on Mat
100 
101    Input Parameters:
102 .  mat - the factored matrix
103 
104    Output Parameter:
105 +  pivot - the pivot value computed
106 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
107          the share the matrix
108 
109    Level: advanced
110 
111    Notes: This routine does not work for factorizations done with external packages.
112    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
113 
114    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
115 
116 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
117 @*/
118 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
119 {
120   PetscFunctionBegin;
121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
122   *pivot = mat->factorerror_zeropivot_value;
123   *row   = mat->factorerror_zeropivot_row;
124   PetscFunctionReturn(0);
125 }
126 
127 /*@
128    MatFactorGetError - gets the error code from a factorization
129 
130    Logically Collective on Mat
131 
132    Input Parameters:
133 .  mat - the factored matrix
134 
135    Output Parameter:
136 .  err  - the error code
137 
138    Level: advanced
139 
140    Notes:    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
141 
142 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
143 @*/
144 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
145 {
146   PetscFunctionBegin;
147   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
148   *err = mat->factorerrortype;
149   PetscFunctionReturn(0);
150 }
151 
152 /*@
153    MatFactorClearError - clears the error code in a factorization
154 
155    Logically Collective on Mat
156 
157    Input Parameter:
158 .  mat - the factored matrix
159 
160    Level: developer
161 
162    Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
163 
164 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
165 @*/
166 PetscErrorCode MatFactorClearError(Mat mat)
167 {
168   PetscFunctionBegin;
169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
170   mat->factorerrortype             = MAT_FACTOR_NOERROR;
171   mat->factorerror_zeropivot_value = 0.0;
172   mat->factorerror_zeropivot_row   = 0;
173   PetscFunctionReturn(0);
174 }
175 
176 static PetscErrorCode MatFindNonzeroRows_Basic(Mat mat,IS *keptrows)
177 {
178   PetscErrorCode    ierr;
179   Vec               r,l;
180   const PetscScalar *al;
181   PetscInt          i,nz,gnz,N,n;
182 
183   PetscFunctionBegin;
184   ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
185   ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
186   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
187   ierr = VecSet(l,0.0);CHKERRQ(ierr);
188   ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
189   ierr = MatMult(mat,r,l);CHKERRQ(ierr);
190   ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
191   for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++;
192   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
193   if (gnz != N) {
194     PetscInt *nzr;
195     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
196     if (nz) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
197     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
198   } else *keptrows = NULL;
199   ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
200   ierr = VecDestroy(&l);CHKERRQ(ierr);
201   ierr = VecDestroy(&r);CHKERRQ(ierr);
202   PetscFunctionReturn(0);
203 }
204 
205 /*@
206       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
207 
208   Input Parameter:
209 .    A  - the matrix
210 
211   Output Parameter:
212 .    keptrows - the rows that are not completely zero
213 
214   Notes: keptrows is set to NULL if all rows are nonzero.
215 
216   Level: intermediate
217 
218  @*/
219 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
220 {
221   PetscErrorCode ierr;
222 
223   PetscFunctionBegin;
224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
225   PetscValidType(mat,1);
226   PetscValidPointer(keptrows,2);
227   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
228   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
229   if (!mat->ops->findnonzerorows) {
230     ierr = MatFindNonzeroRows_Basic(mat,keptrows);CHKERRQ(ierr);
231   } else {
232     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
233   }
234   PetscFunctionReturn(0);
235 }
236 
237 /*@
238       MatFindZeroRows - Locate all rows that are completely zero in the matrix
239 
240   Input Parameter:
241 .    A  - the matrix
242 
243   Output Parameter:
244 .    zerorows - the rows that are completely zero
245 
246   Notes: zerorows is set to NULL if no rows are zero.
247 
248   Level: intermediate
249 
250  @*/
251 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
252 {
253   PetscErrorCode ierr;
254   IS keptrows;
255   PetscInt m, n;
256 
257   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
258   PetscValidType(mat,1);
259 
260   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
261   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
262      In keeping with this convention, we set zerorows to NULL if there are no zero
263      rows. */
264   if (keptrows == NULL) {
265     *zerorows = NULL;
266   } else {
267     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
268     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
269     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
270   }
271   PetscFunctionReturn(0);
272 }
273 
274 /*@
275    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
276 
277    Not Collective
278 
279    Input Parameters:
280 .   A - the matrix
281 
282    Output Parameters:
283 .   a - the diagonal part (which is a SEQUENTIAL matrix)
284 
285    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
286           Use caution, as the reference count on the returned matrix is not incremented and it is used as
287 	  part of the containing MPI Mat's normal operation.
288 
289    Level: advanced
290 
291 @*/
292 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
293 {
294   PetscErrorCode ierr;
295 
296   PetscFunctionBegin;
297   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
298   PetscValidType(A,1);
299   PetscValidPointer(a,3);
300   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
301   if (!A->ops->getdiagonalblock) {
302     PetscMPIInt size;
303     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
304     if (size == 1) {
305       *a = A;
306       PetscFunctionReturn(0);
307     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
308   }
309   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
310   PetscFunctionReturn(0);
311 }
312 
313 /*@
314    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
315 
316    Collective on Mat
317 
318    Input Parameters:
319 .  mat - the matrix
320 
321    Output Parameter:
322 .   trace - the sum of the diagonal entries
323 
324    Level: advanced
325 
326 @*/
327 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
328 {
329   PetscErrorCode ierr;
330   Vec            diag;
331 
332   PetscFunctionBegin;
333   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
334   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
335   ierr = VecSum(diag,trace);CHKERRQ(ierr);
336   ierr = VecDestroy(&diag);CHKERRQ(ierr);
337   PetscFunctionReturn(0);
338 }
339 
340 /*@
341    MatRealPart - Zeros out the imaginary part of the matrix
342 
343    Logically Collective on Mat
344 
345    Input Parameters:
346 .  mat - the matrix
347 
348    Level: advanced
349 
350 
351 .seealso: MatImaginaryPart()
352 @*/
353 PetscErrorCode MatRealPart(Mat mat)
354 {
355   PetscErrorCode ierr;
356 
357   PetscFunctionBegin;
358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
359   PetscValidType(mat,1);
360   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
361   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
362   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
363   MatCheckPreallocated(mat,1);
364   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
365 #if defined(PETSC_HAVE_CUSP)
366   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
367     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
368   }
369 #elif defined(PETSC_HAVE_VIENNACL)
370   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
371     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
372   }
373 #elif defined(PETSC_HAVE_VECCUDA)
374   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
375     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
376   }
377 #endif
378   PetscFunctionReturn(0);
379 }
380 
381 /*@C
382    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
383 
384    Collective on Mat
385 
386    Input Parameter:
387 .  mat - the matrix
388 
389    Output Parameters:
390 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
391 -   ghosts - the global indices of the ghost points
392 
393    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
394 
395    Level: advanced
396 
397 @*/
398 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
399 {
400   PetscErrorCode ierr;
401 
402   PetscFunctionBegin;
403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
404   PetscValidType(mat,1);
405   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
406   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
407   if (!mat->ops->getghosts) {
408     if (nghosts) *nghosts = 0;
409     if (ghosts) *ghosts = 0;
410   } else {
411     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
412   }
413   PetscFunctionReturn(0);
414 }
415 
416 
417 /*@
418    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
419 
420    Logically Collective on Mat
421 
422    Input Parameters:
423 .  mat - the matrix
424 
425    Level: advanced
426 
427 
428 .seealso: MatRealPart()
429 @*/
430 PetscErrorCode MatImaginaryPart(Mat mat)
431 {
432   PetscErrorCode ierr;
433 
434   PetscFunctionBegin;
435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
436   PetscValidType(mat,1);
437   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
438   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
439   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
440   MatCheckPreallocated(mat,1);
441   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
442 #if defined(PETSC_HAVE_CUSP)
443   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
444     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
445   }
446 #elif defined(PETSC_HAVE_VIENNACL)
447   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
448     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
449   }
450 #elif defined(PETSC_HAVE_VECCUDA)
451   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
452     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
453   }
454 #endif
455   PetscFunctionReturn(0);
456 }
457 
458 /*@
459    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
460 
461    Not Collective
462 
463    Input Parameter:
464 .  mat - the matrix
465 
466    Output Parameters:
467 +  missing - is any diagonal missing
468 -  dd - first diagonal entry that is missing (optional) on this process
469 
470    Level: advanced
471 
472 
473 .seealso: MatRealPart()
474 @*/
475 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
476 {
477   PetscErrorCode ierr;
478 
479   PetscFunctionBegin;
480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
481   PetscValidType(mat,1);
482   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
483   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
484   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
485   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
486   PetscFunctionReturn(0);
487 }
488 
489 /*@C
490    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
491    for each row that you get to ensure that your application does
492    not bleed memory.
493 
494    Not Collective
495 
496    Input Parameters:
497 +  mat - the matrix
498 -  row - the row to get
499 
500    Output Parameters:
501 +  ncols -  if not NULL, the number of nonzeros in the row
502 .  cols - if not NULL, the column numbers
503 -  vals - if not NULL, the values
504 
505    Notes:
506    This routine is provided for people who need to have direct access
507    to the structure of a matrix.  We hope that we provide enough
508    high-level matrix routines that few users will need it.
509 
510    MatGetRow() always returns 0-based column indices, regardless of
511    whether the internal representation is 0-based (default) or 1-based.
512 
513    For better efficiency, set cols and/or vals to NULL if you do
514    not wish to extract these quantities.
515 
516    The user can only examine the values extracted with MatGetRow();
517    the values cannot be altered.  To change the matrix entries, one
518    must use MatSetValues().
519 
520    You can only have one call to MatGetRow() outstanding for a particular
521    matrix at a time, per processor. MatGetRow() can only obtain rows
522    associated with the given processor, it cannot get rows from the
523    other processors; for that we suggest using MatCreateSubMatrices(), then
524    MatGetRow() on the submatrix. The row index passed to MatGetRows()
525    is in the global number of rows.
526 
527    Fortran Notes:
528    The calling sequence from Fortran is
529 .vb
530    MatGetRow(matrix,row,ncols,cols,values,ierr)
531          Mat     matrix (input)
532          integer row    (input)
533          integer ncols  (output)
534          integer cols(maxcols) (output)
535          double precision (or double complex) values(maxcols) output
536 .ve
537    where maxcols >= maximum nonzeros in any row of the matrix.
538 
539 
540    Caution:
541    Do not try to change the contents of the output arrays (cols and vals).
542    In some cases, this may corrupt the matrix.
543 
544    Level: advanced
545 
546    Concepts: matrices^row access
547 
548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
549 @*/
550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
551 {
552   PetscErrorCode ierr;
553   PetscInt       incols;
554 
555   PetscFunctionBegin;
556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
557   PetscValidType(mat,1);
558   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
559   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
560   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
561   MatCheckPreallocated(mat,1);
562   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
563   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
564   if (ncols) *ncols = incols;
565   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
566   PetscFunctionReturn(0);
567 }
568 
569 /*@
570    MatConjugate - replaces the matrix values with their complex conjugates
571 
572    Logically Collective on Mat
573 
574    Input Parameters:
575 .  mat - the matrix
576 
577    Level: advanced
578 
579 .seealso:  VecConjugate()
580 @*/
581 PetscErrorCode MatConjugate(Mat mat)
582 {
583 #if defined(PETSC_USE_COMPLEX)
584   PetscErrorCode ierr;
585 
586   PetscFunctionBegin;
587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
588   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
589   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
590   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
591 #if defined(PETSC_HAVE_CUSP)
592   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
593     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
594   }
595 #elif defined(PETSC_HAVE_VIENNACL)
596   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
597     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
598   }
599 #elif defined(PETSC_HAVE_VECCUDA)
600   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
601     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
602   }
603 #endif
604   PetscFunctionReturn(0);
605 #else
606   return 0;
607 #endif
608 }
609 
610 /*@C
611    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
612 
613    Not Collective
614 
615    Input Parameters:
616 +  mat - the matrix
617 .  row - the row to get
618 .  ncols, cols - the number of nonzeros and their columns
619 -  vals - if nonzero the column values
620 
621    Notes:
622    This routine should be called after you have finished examining the entries.
623 
624    This routine zeros out ncols, cols, and vals. This is to prevent accidental
625    us of the array after it has been restored. If you pass NULL, it will
626    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
627 
628    Fortran Notes:
629    The calling sequence from Fortran is
630 .vb
631    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
632       Mat     matrix (input)
633       integer row    (input)
634       integer ncols  (output)
635       integer cols(maxcols) (output)
636       double precision (or double complex) values(maxcols) output
637 .ve
638    Where maxcols >= maximum nonzeros in any row of the matrix.
639 
640    In Fortran MatRestoreRow() MUST be called after MatGetRow()
641    before another call to MatGetRow() can be made.
642 
643    Level: advanced
644 
645 .seealso:  MatGetRow()
646 @*/
647 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
648 {
649   PetscErrorCode ierr;
650 
651   PetscFunctionBegin;
652   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
653   if (ncols) PetscValidIntPointer(ncols,3);
654   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
655   if (!mat->ops->restorerow) PetscFunctionReturn(0);
656   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
657   if (ncols) *ncols = 0;
658   if (cols)  *cols = NULL;
659   if (vals)  *vals = NULL;
660   PetscFunctionReturn(0);
661 }
662 
663 /*@
664    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
665    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
666 
667    Not Collective
668 
669    Input Parameters:
670 +  mat - the matrix
671 
672    Notes:
673    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
674 
675    Level: advanced
676 
677    Concepts: matrices^row access
678 
679 .seealso: MatRestoreRowRowUpperTriangular()
680 @*/
681 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
682 {
683   PetscErrorCode ierr;
684 
685   PetscFunctionBegin;
686   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
687   PetscValidType(mat,1);
688   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
689   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
690   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
691   MatCheckPreallocated(mat,1);
692   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
693   PetscFunctionReturn(0);
694 }
695 
696 /*@
697    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
698 
699    Not Collective
700 
701    Input Parameters:
702 +  mat - the matrix
703 
704    Notes:
705    This routine should be called after you have finished MatGetRow/MatRestoreRow().
706 
707 
708    Level: advanced
709 
710 .seealso:  MatGetRowUpperTriangular()
711 @*/
712 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
713 {
714   PetscErrorCode ierr;
715 
716   PetscFunctionBegin;
717   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
718   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
719   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
720   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
721   PetscFunctionReturn(0);
722 }
723 
724 /*@C
725    MatSetOptionsPrefix - Sets the prefix used for searching for all
726    Mat options in the database.
727 
728    Logically Collective on Mat
729 
730    Input Parameter:
731 +  A - the Mat context
732 -  prefix - the prefix to prepend to all option names
733 
734    Notes:
735    A hyphen (-) must NOT be given at the beginning of the prefix name.
736    The first character of all runtime options is AUTOMATICALLY the hyphen.
737 
738    Level: advanced
739 
740 .keywords: Mat, set, options, prefix, database
741 
742 .seealso: MatSetFromOptions()
743 @*/
744 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
745 {
746   PetscErrorCode ierr;
747 
748   PetscFunctionBegin;
749   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
750   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
751   PetscFunctionReturn(0);
752 }
753 
754 /*@C
755    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
756    Mat options in the database.
757 
758    Logically Collective on Mat
759 
760    Input Parameters:
761 +  A - the Mat context
762 -  prefix - the prefix to prepend to all option names
763 
764    Notes:
765    A hyphen (-) must NOT be given at the beginning of the prefix name.
766    The first character of all runtime options is AUTOMATICALLY the hyphen.
767 
768    Level: advanced
769 
770 .keywords: Mat, append, options, prefix, database
771 
772 .seealso: MatGetOptionsPrefix()
773 @*/
774 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
775 {
776   PetscErrorCode ierr;
777 
778   PetscFunctionBegin;
779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
780   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
781   PetscFunctionReturn(0);
782 }
783 
784 /*@C
785    MatGetOptionsPrefix - Sets the prefix used for searching for all
786    Mat options in the database.
787 
788    Not Collective
789 
790    Input Parameter:
791 .  A - the Mat context
792 
793    Output Parameter:
794 .  prefix - pointer to the prefix string used
795 
796    Notes: On the fortran side, the user should pass in a string 'prefix' of
797    sufficient length to hold the prefix.
798 
799    Level: advanced
800 
801 .keywords: Mat, get, options, prefix, database
802 
803 .seealso: MatAppendOptionsPrefix()
804 @*/
805 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
806 {
807   PetscErrorCode ierr;
808 
809   PetscFunctionBegin;
810   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
811   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
812   PetscFunctionReturn(0);
813 }
814 
815 /*@
816    MatSetUp - Sets up the internal matrix data structures for the later use.
817 
818    Collective on Mat
819 
820    Input Parameters:
821 .  A - the Mat context
822 
823    Notes:
824    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
825 
826    If a suitable preallocation routine is used, this function does not need to be called.
827 
828    See the Performance chapter of the PETSc users manual for how to preallocate matrices
829 
830    Level: beginner
831 
832 .keywords: Mat, setup
833 
834 .seealso: MatCreate(), MatDestroy()
835 @*/
836 PetscErrorCode MatSetUp(Mat A)
837 {
838   PetscMPIInt    size;
839   PetscErrorCode ierr;
840 
841   PetscFunctionBegin;
842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
843   if (!((PetscObject)A)->type_name) {
844     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
845     if (size == 1) {
846       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
847     } else {
848       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
849     }
850   }
851   if (!A->preallocated && A->ops->setup) {
852     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
853     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
854   }
855   if (A->rmap->n < 0 || A->rmap->N < 0) {
856     ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
857   }
858   if (A->cmap->n < 0 || A->cmap->N < 0) {
859     ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
860   }
861   A->preallocated = PETSC_TRUE;
862   PetscFunctionReturn(0);
863 }
864 
865 #if defined(PETSC_HAVE_SAWS)
866 #include <petscviewersaws.h>
867 #endif
868 /*@C
869    MatView - Visualizes a matrix object.
870 
871    Collective on Mat
872 
873    Input Parameters:
874 +  mat - the matrix
875 -  viewer - visualization context
876 
877   Notes:
878   The available visualization contexts include
879 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
880 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
881 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
882 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
883 
884    The user can open alternative visualization contexts with
885 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
886 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
887          specified file; corresponding input uses MatLoad()
888 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
889          an X window display
890 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
891          Currently only the sequential dense and AIJ
892          matrix types support the Socket viewer.
893 
894    The user can call PetscViewerPushFormat() to specify the output
895    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
896    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
897 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
898 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
899 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
900 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
901          format common among all matrix types
902 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
903          format (which is in many cases the same as the default)
904 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
905          size and structure (not the matrix entries)
906 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
907          the matrix structure
908 
909    Options Database Keys:
910 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
911 .  -mat_view ::ascii_info_detail - Prints more detailed info
912 .  -mat_view - Prints matrix in ASCII format
913 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
914 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
915 .  -display <name> - Sets display name (default is host)
916 .  -draw_pause <sec> - Sets number of seconds to pause after display
917 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
918 .  -viewer_socket_machine <machine> -
919 .  -viewer_socket_port <port> -
920 .  -mat_view binary - save matrix to file in binary format
921 -  -viewer_binary_filename <name> -
922    Level: beginner
923 
924    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
925       viewer is used.
926 
927       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
928       viewer is used.
929 
930       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
931       And then use the following mouse functions:
932           left mouse: zoom in
933           middle mouse: zoom out
934           right mouse: continue with the simulation
935 
936    Concepts: matrices^viewing
937    Concepts: matrices^plotting
938    Concepts: matrices^printing
939 
940 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
941           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
942 @*/
943 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
944 {
945   PetscErrorCode    ierr;
946   PetscInt          rows,cols,rbs,cbs;
947   PetscBool         iascii,ibinary;
948   PetscViewerFormat format;
949 #if defined(PETSC_HAVE_SAWS)
950   PetscBool         issaws;
951 #endif
952 
953   PetscFunctionBegin;
954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
955   PetscValidType(mat,1);
956   if (!viewer) {
957     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
958   }
959   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
960   PetscCheckSameComm(mat,1,viewer,2);
961   MatCheckPreallocated(mat,1);
962   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
963   if (ibinary) {
964     PetscBool mpiio;
965     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
966     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
967   }
968 
969   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
970   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
971   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
972   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
973     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
974   }
975 
976 #if defined(PETSC_HAVE_SAWS)
977   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
978 #endif
979   if (iascii) {
980     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
981     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
982     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
983       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
984       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
985       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
986       if (rbs != 1 || cbs != 1) {
987         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
988         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
989       } else {
990         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
991       }
992       if (mat->factortype) {
993         const MatSolverPackage solver;
994         ierr = MatFactorGetSolverPackage(mat,&solver);CHKERRQ(ierr);
995         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
996       }
997       if (mat->ops->getinfo) {
998         MatInfo info;
999         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1000         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1001         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1002       }
1003       if (mat->nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1004       if (mat->nearnullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1005     }
1006 #if defined(PETSC_HAVE_SAWS)
1007   } else if (issaws) {
1008     PetscMPIInt rank;
1009 
1010     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1011     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1012     if (!((PetscObject)mat)->amsmem && !rank) {
1013       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1014     }
1015 #endif
1016   }
1017   if (mat->ops->view) {
1018     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1019     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1020     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1021   }
1022   if (iascii) {
1023     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1024     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1025     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1026       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1027     }
1028   }
1029   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1030   PetscFunctionReturn(0);
1031 }
1032 
1033 #if defined(PETSC_USE_DEBUG)
1034 #include <../src/sys/totalview/tv_data_display.h>
1035 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1036 {
1037   TV_add_row("Local rows", "int", &mat->rmap->n);
1038   TV_add_row("Local columns", "int", &mat->cmap->n);
1039   TV_add_row("Global rows", "int", &mat->rmap->N);
1040   TV_add_row("Global columns", "int", &mat->cmap->N);
1041   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1042   return TV_format_OK;
1043 }
1044 #endif
1045 
1046 /*@C
1047    MatLoad - Loads a matrix that has been stored in binary format
1048    with MatView().  The matrix format is determined from the options database.
1049    Generates a parallel MPI matrix if the communicator has more than one
1050    processor.  The default matrix type is AIJ.
1051 
1052    Collective on PetscViewer
1053 
1054    Input Parameters:
1055 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1056             or some related function before a call to MatLoad()
1057 -  viewer - binary file viewer, created with PetscViewerBinaryOpen()
1058 
1059    Options Database Keys:
1060    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1061    block size
1062 .    -matload_block_size <bs>
1063 
1064    Level: beginner
1065 
1066    Notes:
1067    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1068    Mat before calling this routine if you wish to set it from the options database.
1069 
1070    MatLoad() automatically loads into the options database any options
1071    given in the file filename.info where filename is the name of the file
1072    that was passed to the PetscViewerBinaryOpen(). The options in the info
1073    file will be ignored if you use the -viewer_binary_skip_info option.
1074 
1075    If the type or size of newmat is not set before a call to MatLoad, PETSc
1076    sets the default matrix type AIJ and sets the local and global sizes.
1077    If type and/or size is already set, then the same are used.
1078 
1079    In parallel, each processor can load a subset of rows (or the
1080    entire matrix).  This routine is especially useful when a large
1081    matrix is stored on disk and only part of it is desired on each
1082    processor.  For example, a parallel solver may access only some of
1083    the rows from each processor.  The algorithm used here reads
1084    relatively small blocks of data rather than reading the entire
1085    matrix and then subsetting it.
1086 
1087    Notes for advanced users:
1088    Most users should not need to know the details of the binary storage
1089    format, since MatLoad() and MatView() completely hide these details.
1090    But for anyone who's interested, the standard binary matrix storage
1091    format is
1092 
1093 $    int    MAT_FILE_CLASSID
1094 $    int    number of rows
1095 $    int    number of columns
1096 $    int    total number of nonzeros
1097 $    int    *number nonzeros in each row
1098 $    int    *column indices of all nonzeros (starting index is zero)
1099 $    PetscScalar *values of all nonzeros
1100 
1101    PETSc automatically does the byte swapping for
1102 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1103 linux, Windows and the paragon; thus if you write your own binary
1104 read/write routines you have to swap the bytes; see PetscBinaryRead()
1105 and PetscBinaryWrite() to see how this may be done.
1106 
1107 .keywords: matrix, load, binary, input
1108 
1109 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
1110 
1111  @*/
1112 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1113 {
1114   PetscErrorCode ierr;
1115   PetscBool      isbinary,flg;
1116 
1117   PetscFunctionBegin;
1118   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1119   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1120   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1121   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1122 
1123   if (!((PetscObject)newmat)->type_name) {
1124     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1125   }
1126 
1127   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1128   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1129   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1130   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1131 
1132   flg  = PETSC_FALSE;
1133   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1134   if (flg) {
1135     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1136     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1137   }
1138   flg  = PETSC_FALSE;
1139   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1140   if (flg) {
1141     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1142   }
1143   PetscFunctionReturn(0);
1144 }
1145 
1146 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1147 {
1148   PetscErrorCode ierr;
1149   Mat_Redundant  *redund = *redundant;
1150   PetscInt       i;
1151 
1152   PetscFunctionBegin;
1153   if (redund){
1154     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1155       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1156       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1157       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1158     } else {
1159       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1160       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1161       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1162       for (i=0; i<redund->nrecvs; i++) {
1163         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1164         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1165       }
1166       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1167     }
1168 
1169     if (redund->subcomm) {
1170       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1171     }
1172     ierr = PetscFree(redund);CHKERRQ(ierr);
1173   }
1174   PetscFunctionReturn(0);
1175 }
1176 
1177 /*@
1178    MatDestroy - Frees space taken by a matrix.
1179 
1180    Collective on Mat
1181 
1182    Input Parameter:
1183 .  A - the matrix
1184 
1185    Level: beginner
1186 
1187 @*/
1188 PetscErrorCode MatDestroy(Mat *A)
1189 {
1190   PetscErrorCode ierr;
1191 
1192   PetscFunctionBegin;
1193   if (!*A) PetscFunctionReturn(0);
1194   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1195   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1196 
1197   /* if memory was published with SAWs then destroy it */
1198   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1199   if ((*A)->ops->destroy) {
1200     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1201   }
1202 
1203   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1204   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1205   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1206   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1207   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1208   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1209   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1210   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1211   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1212   PetscFunctionReturn(0);
1213 }
1214 
1215 /*@C
1216    MatSetValues - Inserts or adds a block of values into a matrix.
1217    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1218    MUST be called after all calls to MatSetValues() have been completed.
1219 
1220    Not Collective
1221 
1222    Input Parameters:
1223 +  mat - the matrix
1224 .  v - a logically two-dimensional array of values
1225 .  m, idxm - the number of rows and their global indices
1226 .  n, idxn - the number of columns and their global indices
1227 -  addv - either ADD_VALUES or INSERT_VALUES, where
1228    ADD_VALUES adds values to any existing entries, and
1229    INSERT_VALUES replaces existing entries with new values
1230 
1231    Notes:
1232    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1233       MatSetUp() before using this routine
1234 
1235    By default the values, v, are row-oriented. See MatSetOption() for other options.
1236 
1237    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1238    options cannot be mixed without intervening calls to the assembly
1239    routines.
1240 
1241    MatSetValues() uses 0-based row and column numbers in Fortran
1242    as well as in C.
1243 
1244    Negative indices may be passed in idxm and idxn, these rows and columns are
1245    simply ignored. This allows easily inserting element stiffness matrices
1246    with homogeneous Dirchlet boundary conditions that you don't want represented
1247    in the matrix.
1248 
1249    Efficiency Alert:
1250    The routine MatSetValuesBlocked() may offer much better efficiency
1251    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1252 
1253    Level: beginner
1254 
1255    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
1256                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1257 
1258    Concepts: matrices^putting entries in
1259 
1260 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1261           InsertMode, INSERT_VALUES, ADD_VALUES
1262 @*/
1263 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1264 {
1265   PetscErrorCode ierr;
1266 #if defined(PETSC_USE_DEBUG)
1267   PetscInt       i,j;
1268 #endif
1269 
1270   PetscFunctionBeginHot;
1271   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1272   PetscValidType(mat,1);
1273   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1274   PetscValidIntPointer(idxm,3);
1275   PetscValidIntPointer(idxn,5);
1276   PetscValidScalarPointer(v,6);
1277   MatCheckPreallocated(mat,1);
1278   if (mat->insertmode == NOT_SET_VALUES) {
1279     mat->insertmode = addv;
1280   }
1281 #if defined(PETSC_USE_DEBUG)
1282   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1283   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1284   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1285 
1286   for (i=0; i<m; i++) {
1287     for (j=0; j<n; j++) {
1288       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1289 #if defined(PETSC_USE_COMPLEX)
1290         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1291 #else
1292         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1293 #endif
1294     }
1295   }
1296 #endif
1297 
1298   if (mat->assembled) {
1299     mat->was_assembled = PETSC_TRUE;
1300     mat->assembled     = PETSC_FALSE;
1301   }
1302   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1303   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1304   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1305 #if defined(PETSC_HAVE_CUSP)
1306   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1307     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1308   }
1309 #elif defined(PETSC_HAVE_VIENNACL)
1310   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1311     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1312   }
1313 #elif defined(PETSC_HAVE_VECCUDA)
1314   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1315     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1316   }
1317 #endif
1318   PetscFunctionReturn(0);
1319 }
1320 
1321 
1322 /*@
1323    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1324         values into a matrix
1325 
1326    Not Collective
1327 
1328    Input Parameters:
1329 +  mat - the matrix
1330 .  row - the (block) row to set
1331 -  v - a logically two-dimensional array of values
1332 
1333    Notes:
1334    By the values, v, are column-oriented (for the block version) and sorted
1335 
1336    All the nonzeros in the row must be provided
1337 
1338    The matrix must have previously had its column indices set
1339 
1340    The row must belong to this process
1341 
1342    Level: intermediate
1343 
1344    Concepts: matrices^putting entries in
1345 
1346 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1347           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1348 @*/
1349 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1350 {
1351   PetscErrorCode ierr;
1352   PetscInt       globalrow;
1353 
1354   PetscFunctionBegin;
1355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1356   PetscValidType(mat,1);
1357   PetscValidScalarPointer(v,2);
1358   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1359   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1360 #if defined(PETSC_HAVE_CUSP)
1361   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1362     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1363   }
1364 #elif defined(PETSC_HAVE_VIENNACL)
1365   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1366     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1367   }
1368 #elif defined(PETSC_HAVE_VECCUDA)
1369   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1370     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1371   }
1372 #endif
1373   PetscFunctionReturn(0);
1374 }
1375 
1376 /*@
1377    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1378         values into a matrix
1379 
1380    Not Collective
1381 
1382    Input Parameters:
1383 +  mat - the matrix
1384 .  row - the (block) row to set
1385 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1386 
1387    Notes:
1388    The values, v, are column-oriented for the block version.
1389 
1390    All the nonzeros in the row must be provided
1391 
1392    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1393 
1394    The row must belong to this process
1395 
1396    Level: advanced
1397 
1398    Concepts: matrices^putting entries in
1399 
1400 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1401           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1402 @*/
1403 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1404 {
1405   PetscErrorCode ierr;
1406 
1407   PetscFunctionBeginHot;
1408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1409   PetscValidType(mat,1);
1410   MatCheckPreallocated(mat,1);
1411   PetscValidScalarPointer(v,2);
1412 #if defined(PETSC_USE_DEBUG)
1413   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1414   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1415 #endif
1416   mat->insertmode = INSERT_VALUES;
1417 
1418   if (mat->assembled) {
1419     mat->was_assembled = PETSC_TRUE;
1420     mat->assembled     = PETSC_FALSE;
1421   }
1422   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1423   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1424   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1425   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1426 #if defined(PETSC_HAVE_CUSP)
1427   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1428     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1429   }
1430 #elif defined(PETSC_HAVE_VIENNACL)
1431   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1432     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1433   }
1434 #elif defined(PETSC_HAVE_VECCUDA)
1435   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1436     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1437   }
1438 #endif
1439   PetscFunctionReturn(0);
1440 }
1441 
1442 /*@
1443    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1444      Using structured grid indexing
1445 
1446    Not Collective
1447 
1448    Input Parameters:
1449 +  mat - the matrix
1450 .  m - number of rows being entered
1451 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1452 .  n - number of columns being entered
1453 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1454 .  v - a logically two-dimensional array of values
1455 -  addv - either ADD_VALUES or INSERT_VALUES, where
1456    ADD_VALUES adds values to any existing entries, and
1457    INSERT_VALUES replaces existing entries with new values
1458 
1459    Notes:
1460    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1461 
1462    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1463    options cannot be mixed without intervening calls to the assembly
1464    routines.
1465 
1466    The grid coordinates are across the entire grid, not just the local portion
1467 
1468    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1469    as well as in C.
1470 
1471    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1472 
1473    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1474    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1475 
1476    The columns and rows in the stencil passed in MUST be contained within the
1477    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1478    if you create a DMDA with an overlap of one grid level and on a particular process its first
1479    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1480    first i index you can use in your column and row indices in MatSetStencil() is 5.
1481 
1482    In Fortran idxm and idxn should be declared as
1483 $     MatStencil idxm(4,m),idxn(4,n)
1484    and the values inserted using
1485 $    idxm(MatStencil_i,1) = i
1486 $    idxm(MatStencil_j,1) = j
1487 $    idxm(MatStencil_k,1) = k
1488 $    idxm(MatStencil_c,1) = c
1489    etc
1490 
1491    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1492    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1493    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1494    DM_BOUNDARY_PERIODIC boundary type.
1495 
1496    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1497    a single value per point) you can skip filling those indices.
1498 
1499    Inspired by the structured grid interface to the HYPRE package
1500    (http://www.llnl.gov/CASC/hypre)
1501 
1502    Efficiency Alert:
1503    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1504    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1505 
1506    Level: beginner
1507 
1508    Concepts: matrices^putting entries in
1509 
1510 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1511           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1512 @*/
1513 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1514 {
1515   PetscErrorCode ierr;
1516   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1517   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1518   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1519 
1520   PetscFunctionBegin;
1521   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1522   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1523   PetscValidType(mat,1);
1524   PetscValidIntPointer(idxm,3);
1525   PetscValidIntPointer(idxn,5);
1526   PetscValidScalarPointer(v,6);
1527 
1528   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1529     jdxm = buf; jdxn = buf+m;
1530   } else {
1531     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1532     jdxm = bufm; jdxn = bufn;
1533   }
1534   for (i=0; i<m; i++) {
1535     for (j=0; j<3-sdim; j++) dxm++;
1536     tmp = *dxm++ - starts[0];
1537     for (j=0; j<dim-1; j++) {
1538       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1539       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1540     }
1541     if (mat->stencil.noc) dxm++;
1542     jdxm[i] = tmp;
1543   }
1544   for (i=0; i<n; i++) {
1545     for (j=0; j<3-sdim; j++) dxn++;
1546     tmp = *dxn++ - starts[0];
1547     for (j=0; j<dim-1; j++) {
1548       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1549       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1550     }
1551     if (mat->stencil.noc) dxn++;
1552     jdxn[i] = tmp;
1553   }
1554   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1555   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1556   PetscFunctionReturn(0);
1557 }
1558 
1559 /*@
1560    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1561      Using structured grid indexing
1562 
1563    Not Collective
1564 
1565    Input Parameters:
1566 +  mat - the matrix
1567 .  m - number of rows being entered
1568 .  idxm - grid coordinates for matrix rows being entered
1569 .  n - number of columns being entered
1570 .  idxn - grid coordinates for matrix columns being entered
1571 .  v - a logically two-dimensional array of values
1572 -  addv - either ADD_VALUES or INSERT_VALUES, where
1573    ADD_VALUES adds values to any existing entries, and
1574    INSERT_VALUES replaces existing entries with new values
1575 
1576    Notes:
1577    By default the values, v, are row-oriented and unsorted.
1578    See MatSetOption() for other options.
1579 
1580    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1581    options cannot be mixed without intervening calls to the assembly
1582    routines.
1583 
1584    The grid coordinates are across the entire grid, not just the local portion
1585 
1586    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1587    as well as in C.
1588 
1589    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1590 
1591    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1592    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1593 
1594    The columns and rows in the stencil passed in MUST be contained within the
1595    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1596    if you create a DMDA with an overlap of one grid level and on a particular process its first
1597    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1598    first i index you can use in your column and row indices in MatSetStencil() is 5.
1599 
1600    In Fortran idxm and idxn should be declared as
1601 $     MatStencil idxm(4,m),idxn(4,n)
1602    and the values inserted using
1603 $    idxm(MatStencil_i,1) = i
1604 $    idxm(MatStencil_j,1) = j
1605 $    idxm(MatStencil_k,1) = k
1606    etc
1607 
1608    Negative indices may be passed in idxm and idxn, these rows and columns are
1609    simply ignored. This allows easily inserting element stiffness matrices
1610    with homogeneous Dirchlet boundary conditions that you don't want represented
1611    in the matrix.
1612 
1613    Inspired by the structured grid interface to the HYPRE package
1614    (http://www.llnl.gov/CASC/hypre)
1615 
1616    Level: beginner
1617 
1618    Concepts: matrices^putting entries in
1619 
1620 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1621           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1622           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1623 @*/
1624 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1625 {
1626   PetscErrorCode ierr;
1627   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1628   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1629   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1630 
1631   PetscFunctionBegin;
1632   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1633   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1634   PetscValidType(mat,1);
1635   PetscValidIntPointer(idxm,3);
1636   PetscValidIntPointer(idxn,5);
1637   PetscValidScalarPointer(v,6);
1638 
1639   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1640     jdxm = buf; jdxn = buf+m;
1641   } else {
1642     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1643     jdxm = bufm; jdxn = bufn;
1644   }
1645   for (i=0; i<m; i++) {
1646     for (j=0; j<3-sdim; j++) dxm++;
1647     tmp = *dxm++ - starts[0];
1648     for (j=0; j<sdim-1; j++) {
1649       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1650       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1651     }
1652     dxm++;
1653     jdxm[i] = tmp;
1654   }
1655   for (i=0; i<n; i++) {
1656     for (j=0; j<3-sdim; j++) dxn++;
1657     tmp = *dxn++ - starts[0];
1658     for (j=0; j<sdim-1; j++) {
1659       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1660       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1661     }
1662     dxn++;
1663     jdxn[i] = tmp;
1664   }
1665   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1666   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1667 #if defined(PETSC_HAVE_CUSP)
1668   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1669     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1670   }
1671 #elif defined(PETSC_HAVE_VIENNACL)
1672   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1673     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1674   }
1675 #elif defined(PETSC_HAVE_VECCUDA)
1676   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1677     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1678   }
1679 #endif
1680   PetscFunctionReturn(0);
1681 }
1682 
1683 /*@
1684    MatSetStencil - Sets the grid information for setting values into a matrix via
1685         MatSetValuesStencil()
1686 
1687    Not Collective
1688 
1689    Input Parameters:
1690 +  mat - the matrix
1691 .  dim - dimension of the grid 1, 2, or 3
1692 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1693 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1694 -  dof - number of degrees of freedom per node
1695 
1696 
1697    Inspired by the structured grid interface to the HYPRE package
1698    (www.llnl.gov/CASC/hyper)
1699 
1700    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1701    user.
1702 
1703    Level: beginner
1704 
1705    Concepts: matrices^putting entries in
1706 
1707 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1708           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1709 @*/
1710 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1711 {
1712   PetscInt i;
1713 
1714   PetscFunctionBegin;
1715   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1716   PetscValidIntPointer(dims,3);
1717   PetscValidIntPointer(starts,4);
1718 
1719   mat->stencil.dim = dim + (dof > 1);
1720   for (i=0; i<dim; i++) {
1721     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1722     mat->stencil.starts[i] = starts[dim-i-1];
1723   }
1724   mat->stencil.dims[dim]   = dof;
1725   mat->stencil.starts[dim] = 0;
1726   mat->stencil.noc         = (PetscBool)(dof == 1);
1727   PetscFunctionReturn(0);
1728 }
1729 
1730 /*@C
1731    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1732 
1733    Not Collective
1734 
1735    Input Parameters:
1736 +  mat - the matrix
1737 .  v - a logically two-dimensional array of values
1738 .  m, idxm - the number of block rows and their global block indices
1739 .  n, idxn - the number of block columns and their global block indices
1740 -  addv - either ADD_VALUES or INSERT_VALUES, where
1741    ADD_VALUES adds values to any existing entries, and
1742    INSERT_VALUES replaces existing entries with new values
1743 
1744    Notes:
1745    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1746    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1747 
1748    The m and n count the NUMBER of blocks in the row direction and column direction,
1749    NOT the total number of rows/columns; for example, if the block size is 2 and
1750    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1751    The values in idxm would be 1 2; that is the first index for each block divided by
1752    the block size.
1753 
1754    Note that you must call MatSetBlockSize() when constructing this matrix (before
1755    preallocating it).
1756 
1757    By default the values, v, are row-oriented, so the layout of
1758    v is the same as for MatSetValues(). See MatSetOption() for other options.
1759 
1760    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1761    options cannot be mixed without intervening calls to the assembly
1762    routines.
1763 
1764    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1765    as well as in C.
1766 
1767    Negative indices may be passed in idxm and idxn, these rows and columns are
1768    simply ignored. This allows easily inserting element stiffness matrices
1769    with homogeneous Dirchlet boundary conditions that you don't want represented
1770    in the matrix.
1771 
1772    Each time an entry is set within a sparse matrix via MatSetValues(),
1773    internal searching must be done to determine where to place the
1774    data in the matrix storage space.  By instead inserting blocks of
1775    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1776    reduced.
1777 
1778    Example:
1779 $   Suppose m=n=2 and block size(bs) = 2 The array is
1780 $
1781 $   1  2  | 3  4
1782 $   5  6  | 7  8
1783 $   - - - | - - -
1784 $   9  10 | 11 12
1785 $   13 14 | 15 16
1786 $
1787 $   v[] should be passed in like
1788 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1789 $
1790 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1791 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1792 
1793    Level: intermediate
1794 
1795    Concepts: matrices^putting entries in blocked
1796 
1797 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1798 @*/
1799 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1800 {
1801   PetscErrorCode ierr;
1802 
1803   PetscFunctionBeginHot;
1804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1805   PetscValidType(mat,1);
1806   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1807   PetscValidIntPointer(idxm,3);
1808   PetscValidIntPointer(idxn,5);
1809   PetscValidScalarPointer(v,6);
1810   MatCheckPreallocated(mat,1);
1811   if (mat->insertmode == NOT_SET_VALUES) {
1812     mat->insertmode = addv;
1813   }
1814 #if defined(PETSC_USE_DEBUG)
1815   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1816   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1817   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1818 #endif
1819 
1820   if (mat->assembled) {
1821     mat->was_assembled = PETSC_TRUE;
1822     mat->assembled     = PETSC_FALSE;
1823   }
1824   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1825   if (mat->ops->setvaluesblocked) {
1826     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1827   } else {
1828     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1829     PetscInt i,j,bs,cbs;
1830     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1831     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1832       iidxm = buf; iidxn = buf + m*bs;
1833     } else {
1834       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1835       iidxm = bufr; iidxn = bufc;
1836     }
1837     for (i=0; i<m; i++) {
1838       for (j=0; j<bs; j++) {
1839         iidxm[i*bs+j] = bs*idxm[i] + j;
1840       }
1841     }
1842     for (i=0; i<n; i++) {
1843       for (j=0; j<cbs; j++) {
1844         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1845       }
1846     }
1847     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1848     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1849   }
1850   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1851 #if defined(PETSC_HAVE_CUSP)
1852   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1853     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1854   }
1855 #elif defined(PETSC_HAVE_VIENNACL)
1856   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1857     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1858   }
1859 #elif defined(PETSC_HAVE_VECCUDA)
1860   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1861     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1862   }
1863 #endif
1864   PetscFunctionReturn(0);
1865 }
1866 
1867 /*@
1868    MatGetValues - Gets a block of values from a matrix.
1869 
1870    Not Collective; currently only returns a local block
1871 
1872    Input Parameters:
1873 +  mat - the matrix
1874 .  v - a logically two-dimensional array for storing the values
1875 .  m, idxm - the number of rows and their global indices
1876 -  n, idxn - the number of columns and their global indices
1877 
1878    Notes:
1879    The user must allocate space (m*n PetscScalars) for the values, v.
1880    The values, v, are then returned in a row-oriented format,
1881    analogous to that used by default in MatSetValues().
1882 
1883    MatGetValues() uses 0-based row and column numbers in
1884    Fortran as well as in C.
1885 
1886    MatGetValues() requires that the matrix has been assembled
1887    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1888    MatSetValues() and MatGetValues() CANNOT be made in succession
1889    without intermediate matrix assembly.
1890 
1891    Negative row or column indices will be ignored and those locations in v[] will be
1892    left unchanged.
1893 
1894    Level: advanced
1895 
1896    Concepts: matrices^accessing values
1897 
1898 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1899 @*/
1900 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1901 {
1902   PetscErrorCode ierr;
1903 
1904   PetscFunctionBegin;
1905   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1906   PetscValidType(mat,1);
1907   if (!m || !n) PetscFunctionReturn(0);
1908   PetscValidIntPointer(idxm,3);
1909   PetscValidIntPointer(idxn,5);
1910   PetscValidScalarPointer(v,6);
1911   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1912   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1913   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1914   MatCheckPreallocated(mat,1);
1915 
1916   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1917   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1918   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1919   PetscFunctionReturn(0);
1920 }
1921 
1922 /*@
1923   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1924   the same size. Currently, this can only be called once and creates the given matrix.
1925 
1926   Not Collective
1927 
1928   Input Parameters:
1929 + mat - the matrix
1930 . nb - the number of blocks
1931 . bs - the number of rows (and columns) in each block
1932 . rows - a concatenation of the rows for each block
1933 - v - a concatenation of logically two-dimensional arrays of values
1934 
1935   Notes:
1936   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1937 
1938   Level: advanced
1939 
1940   Concepts: matrices^putting entries in
1941 
1942 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1943           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1944 @*/
1945 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1946 {
1947   PetscErrorCode ierr;
1948 
1949   PetscFunctionBegin;
1950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1951   PetscValidType(mat,1);
1952   PetscValidScalarPointer(rows,4);
1953   PetscValidScalarPointer(v,5);
1954 #if defined(PETSC_USE_DEBUG)
1955   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1956 #endif
1957 
1958   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1959   if (mat->ops->setvaluesbatch) {
1960     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1961   } else {
1962     PetscInt b;
1963     for (b = 0; b < nb; ++b) {
1964       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1965     }
1966   }
1967   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1968   PetscFunctionReturn(0);
1969 }
1970 
1971 /*@
1972    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1973    the routine MatSetValuesLocal() to allow users to insert matrix entries
1974    using a local (per-processor) numbering.
1975 
1976    Not Collective
1977 
1978    Input Parameters:
1979 +  x - the matrix
1980 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1981 - cmapping - column mapping
1982 
1983    Level: intermediate
1984 
1985    Concepts: matrices^local to global mapping
1986    Concepts: local to global mapping^for matrices
1987 
1988 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1989 @*/
1990 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1991 {
1992   PetscErrorCode ierr;
1993 
1994   PetscFunctionBegin;
1995   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
1996   PetscValidType(x,1);
1997   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
1998   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
1999 
2000   if (x->ops->setlocaltoglobalmapping) {
2001     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2002   } else {
2003     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2004     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2005   }
2006   PetscFunctionReturn(0);
2007 }
2008 
2009 
2010 /*@
2011    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2012 
2013    Not Collective
2014 
2015    Input Parameters:
2016 .  A - the matrix
2017 
2018    Output Parameters:
2019 + rmapping - row mapping
2020 - cmapping - column mapping
2021 
2022    Level: advanced
2023 
2024    Concepts: matrices^local to global mapping
2025    Concepts: local to global mapping^for matrices
2026 
2027 .seealso:  MatSetValuesLocal()
2028 @*/
2029 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2030 {
2031   PetscFunctionBegin;
2032   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2033   PetscValidType(A,1);
2034   if (rmapping) PetscValidPointer(rmapping,2);
2035   if (cmapping) PetscValidPointer(cmapping,3);
2036   if (rmapping) *rmapping = A->rmap->mapping;
2037   if (cmapping) *cmapping = A->cmap->mapping;
2038   PetscFunctionReturn(0);
2039 }
2040 
2041 /*@
2042    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2043 
2044    Not Collective
2045 
2046    Input Parameters:
2047 .  A - the matrix
2048 
2049    Output Parameters:
2050 + rmap - row layout
2051 - cmap - column layout
2052 
2053    Level: advanced
2054 
2055 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2056 @*/
2057 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2058 {
2059   PetscFunctionBegin;
2060   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2061   PetscValidType(A,1);
2062   if (rmap) PetscValidPointer(rmap,2);
2063   if (cmap) PetscValidPointer(cmap,3);
2064   if (rmap) *rmap = A->rmap;
2065   if (cmap) *cmap = A->cmap;
2066   PetscFunctionReturn(0);
2067 }
2068 
2069 /*@C
2070    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2071    using a local ordering of the nodes.
2072 
2073    Not Collective
2074 
2075    Input Parameters:
2076 +  mat - the matrix
2077 .  nrow, irow - number of rows and their local indices
2078 .  ncol, icol - number of columns and their local indices
2079 .  y -  a logically two-dimensional array of values
2080 -  addv - either INSERT_VALUES or ADD_VALUES, where
2081    ADD_VALUES adds values to any existing entries, and
2082    INSERT_VALUES replaces existing entries with new values
2083 
2084    Notes:
2085    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2086       MatSetUp() before using this routine
2087 
2088    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2089 
2090    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2091    options cannot be mixed without intervening calls to the assembly
2092    routines.
2093 
2094    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2095    MUST be called after all calls to MatSetValuesLocal() have been completed.
2096 
2097    Level: intermediate
2098 
2099    Concepts: matrices^putting entries in with local numbering
2100 
2101    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2102                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2103 
2104 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2105            MatSetValueLocal()
2106 @*/
2107 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2108 {
2109   PetscErrorCode ierr;
2110 
2111   PetscFunctionBeginHot;
2112   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2113   PetscValidType(mat,1);
2114   MatCheckPreallocated(mat,1);
2115   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2116   PetscValidIntPointer(irow,3);
2117   PetscValidIntPointer(icol,5);
2118   PetscValidScalarPointer(y,6);
2119   if (mat->insertmode == NOT_SET_VALUES) {
2120     mat->insertmode = addv;
2121   }
2122 #if defined(PETSC_USE_DEBUG)
2123   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2124   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2125   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2126 #endif
2127 
2128   if (mat->assembled) {
2129     mat->was_assembled = PETSC_TRUE;
2130     mat->assembled     = PETSC_FALSE;
2131   }
2132   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2133   if (mat->ops->setvalueslocal) {
2134     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2135   } else {
2136     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2137     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2138       irowm = buf; icolm = buf+nrow;
2139     } else {
2140       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2141       irowm = bufr; icolm = bufc;
2142     }
2143     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2144     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2145     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2146     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2147   }
2148   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2149 #if defined(PETSC_HAVE_CUSP)
2150   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2151     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2152   }
2153 #elif defined(PETSC_HAVE_VIENNACL)
2154   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2155     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2156   }
2157 #elif defined(PETSC_HAVE_VECCUDA)
2158   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2159     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2160   }
2161 #endif
2162   PetscFunctionReturn(0);
2163 }
2164 
2165 /*@C
2166    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2167    using a local ordering of the nodes a block at a time.
2168 
2169    Not Collective
2170 
2171    Input Parameters:
2172 +  x - the matrix
2173 .  nrow, irow - number of rows and their local indices
2174 .  ncol, icol - number of columns and their local indices
2175 .  y -  a logically two-dimensional array of values
2176 -  addv - either INSERT_VALUES or ADD_VALUES, where
2177    ADD_VALUES adds values to any existing entries, and
2178    INSERT_VALUES replaces existing entries with new values
2179 
2180    Notes:
2181    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2182       MatSetUp() before using this routine
2183 
2184    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2185       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2186 
2187    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2188    options cannot be mixed without intervening calls to the assembly
2189    routines.
2190 
2191    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2192    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2193 
2194    Level: intermediate
2195 
2196    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2197                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2198 
2199    Concepts: matrices^putting blocked values in with local numbering
2200 
2201 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2202            MatSetValuesLocal(),  MatSetValuesBlocked()
2203 @*/
2204 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2205 {
2206   PetscErrorCode ierr;
2207 
2208   PetscFunctionBeginHot;
2209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2210   PetscValidType(mat,1);
2211   MatCheckPreallocated(mat,1);
2212   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2213   PetscValidIntPointer(irow,3);
2214   PetscValidIntPointer(icol,5);
2215   PetscValidScalarPointer(y,6);
2216   if (mat->insertmode == NOT_SET_VALUES) {
2217     mat->insertmode = addv;
2218   }
2219 #if defined(PETSC_USE_DEBUG)
2220   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2221   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2222   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2223 #endif
2224 
2225   if (mat->assembled) {
2226     mat->was_assembled = PETSC_TRUE;
2227     mat->assembled     = PETSC_FALSE;
2228   }
2229   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2230   if (mat->ops->setvaluesblockedlocal) {
2231     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2232   } else {
2233     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2234     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2235       irowm = buf; icolm = buf + nrow;
2236     } else {
2237       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2238       irowm = bufr; icolm = bufc;
2239     }
2240     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2241     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2242     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2243     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2244   }
2245   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2246 #if defined(PETSC_HAVE_CUSP)
2247   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2248     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2249   }
2250 #elif defined(PETSC_HAVE_VIENNACL)
2251   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2252     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2253   }
2254 #elif defined(PETSC_HAVE_VECCUDA)
2255   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2256     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2257   }
2258 #endif
2259   PetscFunctionReturn(0);
2260 }
2261 
2262 /*@
2263    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2264 
2265    Collective on Mat and Vec
2266 
2267    Input Parameters:
2268 +  mat - the matrix
2269 -  x   - the vector to be multiplied
2270 
2271    Output Parameters:
2272 .  y - the result
2273 
2274    Notes:
2275    The vectors x and y cannot be the same.  I.e., one cannot
2276    call MatMult(A,y,y).
2277 
2278    Level: developer
2279 
2280    Concepts: matrix-vector product
2281 
2282 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2283 @*/
2284 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2285 {
2286   PetscErrorCode ierr;
2287 
2288   PetscFunctionBegin;
2289   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2290   PetscValidType(mat,1);
2291   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2292   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2293 
2294   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2295   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2296   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2297   MatCheckPreallocated(mat,1);
2298 
2299   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2300   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2301   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2302   PetscFunctionReturn(0);
2303 }
2304 
2305 /* --------------------------------------------------------*/
2306 /*@
2307    MatMult - Computes the matrix-vector product, y = Ax.
2308 
2309    Neighbor-wise Collective on Mat and Vec
2310 
2311    Input Parameters:
2312 +  mat - the matrix
2313 -  x   - the vector to be multiplied
2314 
2315    Output Parameters:
2316 .  y - the result
2317 
2318    Notes:
2319    The vectors x and y cannot be the same.  I.e., one cannot
2320    call MatMult(A,y,y).
2321 
2322    Level: beginner
2323 
2324    Concepts: matrix-vector product
2325 
2326 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2327 @*/
2328 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2329 {
2330   PetscErrorCode ierr;
2331 
2332   PetscFunctionBegin;
2333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2334   PetscValidType(mat,1);
2335   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2336   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2337   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2338   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2339   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2340 #if !defined(PETSC_HAVE_CONSTRAINTS)
2341   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2342   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2343   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2344 #endif
2345   VecLocked(y,3);
2346   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2347   MatCheckPreallocated(mat,1);
2348 
2349   ierr = VecLockPush(x);CHKERRQ(ierr);
2350   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2351   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2352   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2353   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2354   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2355   ierr = VecLockPop(x);CHKERRQ(ierr);
2356   PetscFunctionReturn(0);
2357 }
2358 
2359 /*@
2360    MatMultTranspose - Computes matrix transpose times a vector.
2361 
2362    Neighbor-wise Collective on Mat and Vec
2363 
2364    Input Parameters:
2365 +  mat - the matrix
2366 -  x   - the vector to be multilplied
2367 
2368    Output Parameters:
2369 .  y - the result
2370 
2371    Notes:
2372    The vectors x and y cannot be the same.  I.e., one cannot
2373    call MatMultTranspose(A,y,y).
2374 
2375    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2376    use MatMultHermitianTranspose()
2377 
2378    Level: beginner
2379 
2380    Concepts: matrix vector product^transpose
2381 
2382 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2383 @*/
2384 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2385 {
2386   PetscErrorCode ierr;
2387 
2388   PetscFunctionBegin;
2389   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2390   PetscValidType(mat,1);
2391   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2392   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2393 
2394   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2395   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2396   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2397 #if !defined(PETSC_HAVE_CONSTRAINTS)
2398   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2399   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2400 #endif
2401   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2402   MatCheckPreallocated(mat,1);
2403 
2404   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2405   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2406   ierr = VecLockPush(x);CHKERRQ(ierr);
2407   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2408   ierr = VecLockPop(x);CHKERRQ(ierr);
2409   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2410   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2411   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2412   PetscFunctionReturn(0);
2413 }
2414 
2415 /*@
2416    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2417 
2418    Neighbor-wise Collective on Mat and Vec
2419 
2420    Input Parameters:
2421 +  mat - the matrix
2422 -  x   - the vector to be multilplied
2423 
2424    Output Parameters:
2425 .  y - the result
2426 
2427    Notes:
2428    The vectors x and y cannot be the same.  I.e., one cannot
2429    call MatMultHermitianTranspose(A,y,y).
2430 
2431    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2432 
2433    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2434 
2435    Level: beginner
2436 
2437    Concepts: matrix vector product^transpose
2438 
2439 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2440 @*/
2441 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2442 {
2443   PetscErrorCode ierr;
2444   Vec            w;
2445 
2446   PetscFunctionBegin;
2447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2448   PetscValidType(mat,1);
2449   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2450   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2451 
2452   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2453   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2454   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2455 #if !defined(PETSC_HAVE_CONSTRAINTS)
2456   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2457   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2458 #endif
2459   MatCheckPreallocated(mat,1);
2460 
2461   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2462   if (mat->ops->multhermitiantranspose) {
2463     ierr = VecLockPush(x);CHKERRQ(ierr);
2464     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2465     ierr = VecLockPop(x);CHKERRQ(ierr);
2466   } else {
2467     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2468     ierr = VecCopy(x,w);CHKERRQ(ierr);
2469     ierr = VecConjugate(w);CHKERRQ(ierr);
2470     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2471     ierr = VecDestroy(&w);CHKERRQ(ierr);
2472     ierr = VecConjugate(y);CHKERRQ(ierr);
2473   }
2474   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2475   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2476   PetscFunctionReturn(0);
2477 }
2478 
2479 /*@
2480     MatMultAdd -  Computes v3 = v2 + A * v1.
2481 
2482     Neighbor-wise Collective on Mat and Vec
2483 
2484     Input Parameters:
2485 +   mat - the matrix
2486 -   v1, v2 - the vectors
2487 
2488     Output Parameters:
2489 .   v3 - the result
2490 
2491     Notes:
2492     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2493     call MatMultAdd(A,v1,v2,v1).
2494 
2495     Level: beginner
2496 
2497     Concepts: matrix vector product^addition
2498 
2499 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2500 @*/
2501 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2502 {
2503   PetscErrorCode ierr;
2504 
2505   PetscFunctionBegin;
2506   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2507   PetscValidType(mat,1);
2508   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2509   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2510   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2511 
2512   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2513   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2514   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2515   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2516      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2517   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2518   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2519   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2520   MatCheckPreallocated(mat,1);
2521 
2522   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2523   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2524   ierr = VecLockPush(v1);CHKERRQ(ierr);
2525   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2526   ierr = VecLockPop(v1);CHKERRQ(ierr);
2527   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2528   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2529   PetscFunctionReturn(0);
2530 }
2531 
2532 /*@
2533    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2534 
2535    Neighbor-wise Collective on Mat and Vec
2536 
2537    Input Parameters:
2538 +  mat - the matrix
2539 -  v1, v2 - the vectors
2540 
2541    Output Parameters:
2542 .  v3 - the result
2543 
2544    Notes:
2545    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2546    call MatMultTransposeAdd(A,v1,v2,v1).
2547 
2548    Level: beginner
2549 
2550    Concepts: matrix vector product^transpose and addition
2551 
2552 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2553 @*/
2554 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2555 {
2556   PetscErrorCode ierr;
2557 
2558   PetscFunctionBegin;
2559   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2560   PetscValidType(mat,1);
2561   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2562   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2563   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2564 
2565   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2566   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2567   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2568   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2569   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2570   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2571   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2572   MatCheckPreallocated(mat,1);
2573 
2574   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2575   ierr = VecLockPush(v1);CHKERRQ(ierr);
2576   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2577   ierr = VecLockPop(v1);CHKERRQ(ierr);
2578   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2579   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2580   PetscFunctionReturn(0);
2581 }
2582 
2583 /*@
2584    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2585 
2586    Neighbor-wise Collective on Mat and Vec
2587 
2588    Input Parameters:
2589 +  mat - the matrix
2590 -  v1, v2 - the vectors
2591 
2592    Output Parameters:
2593 .  v3 - the result
2594 
2595    Notes:
2596    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2597    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2598 
2599    Level: beginner
2600 
2601    Concepts: matrix vector product^transpose and addition
2602 
2603 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2604 @*/
2605 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2606 {
2607   PetscErrorCode ierr;
2608 
2609   PetscFunctionBegin;
2610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2611   PetscValidType(mat,1);
2612   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2613   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2614   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2615 
2616   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2617   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2618   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2619   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2620   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2621   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2622   MatCheckPreallocated(mat,1);
2623 
2624   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2625   ierr = VecLockPush(v1);CHKERRQ(ierr);
2626   if (mat->ops->multhermitiantransposeadd) {
2627     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2628    } else {
2629     Vec w,z;
2630     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2631     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2632     ierr = VecConjugate(w);CHKERRQ(ierr);
2633     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2634     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2635     ierr = VecDestroy(&w);CHKERRQ(ierr);
2636     ierr = VecConjugate(z);CHKERRQ(ierr);
2637     ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2638     ierr = VecDestroy(&z);CHKERRQ(ierr);
2639   }
2640   ierr = VecLockPop(v1);CHKERRQ(ierr);
2641   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2642   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2643   PetscFunctionReturn(0);
2644 }
2645 
2646 /*@
2647    MatMultConstrained - The inner multiplication routine for a
2648    constrained matrix P^T A P.
2649 
2650    Neighbor-wise Collective on Mat and Vec
2651 
2652    Input Parameters:
2653 +  mat - the matrix
2654 -  x   - the vector to be multilplied
2655 
2656    Output Parameters:
2657 .  y - the result
2658 
2659    Notes:
2660    The vectors x and y cannot be the same.  I.e., one cannot
2661    call MatMult(A,y,y).
2662 
2663    Level: beginner
2664 
2665 .keywords: matrix, multiply, matrix-vector product, constraint
2666 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2667 @*/
2668 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2669 {
2670   PetscErrorCode ierr;
2671 
2672   PetscFunctionBegin;
2673   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2674   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2675   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2676   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2677   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2678   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2679   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2680   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2681   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2682 
2683   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2684   ierr = VecLockPush(x);CHKERRQ(ierr);
2685   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2686   ierr = VecLockPop(x);CHKERRQ(ierr);
2687   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2688   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2689   PetscFunctionReturn(0);
2690 }
2691 
2692 /*@
2693    MatMultTransposeConstrained - The inner multiplication routine for a
2694    constrained matrix P^T A^T P.
2695 
2696    Neighbor-wise Collective on Mat and Vec
2697 
2698    Input Parameters:
2699 +  mat - the matrix
2700 -  x   - the vector to be multilplied
2701 
2702    Output Parameters:
2703 .  y - the result
2704 
2705    Notes:
2706    The vectors x and y cannot be the same.  I.e., one cannot
2707    call MatMult(A,y,y).
2708 
2709    Level: beginner
2710 
2711 .keywords: matrix, multiply, matrix-vector product, constraint
2712 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2713 @*/
2714 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2715 {
2716   PetscErrorCode ierr;
2717 
2718   PetscFunctionBegin;
2719   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2720   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2721   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2722   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2723   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2724   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2725   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2726   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2727 
2728   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2729   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2730   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2731   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2732   PetscFunctionReturn(0);
2733 }
2734 
2735 /*@C
2736    MatGetFactorType - gets the type of factorization it is
2737 
2738    Note Collective
2739    as the flag
2740 
2741    Input Parameters:
2742 .  mat - the matrix
2743 
2744    Output Parameters:
2745 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2746 
2747     Level: intermediate
2748 
2749 .seealso:    MatFactorType, MatGetFactor()
2750 @*/
2751 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2752 {
2753   PetscFunctionBegin;
2754   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2755   PetscValidType(mat,1);
2756   *t = mat->factortype;
2757   PetscFunctionReturn(0);
2758 }
2759 
2760 /* ------------------------------------------------------------*/
2761 /*@C
2762    MatGetInfo - Returns information about matrix storage (number of
2763    nonzeros, memory, etc.).
2764 
2765    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2766 
2767    Input Parameters:
2768 .  mat - the matrix
2769 
2770    Output Parameters:
2771 +  flag - flag indicating the type of parameters to be returned
2772    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2773    MAT_GLOBAL_SUM - sum over all processors)
2774 -  info - matrix information context
2775 
2776    Notes:
2777    The MatInfo context contains a variety of matrix data, including
2778    number of nonzeros allocated and used, number of mallocs during
2779    matrix assembly, etc.  Additional information for factored matrices
2780    is provided (such as the fill ratio, number of mallocs during
2781    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2782    when using the runtime options
2783 $       -info -mat_view ::ascii_info
2784 
2785    Example for C/C++ Users:
2786    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2787    data within the MatInfo context.  For example,
2788 .vb
2789       MatInfo info;
2790       Mat     A;
2791       double  mal, nz_a, nz_u;
2792 
2793       MatGetInfo(A,MAT_LOCAL,&info);
2794       mal  = info.mallocs;
2795       nz_a = info.nz_allocated;
2796 .ve
2797 
2798    Example for Fortran Users:
2799    Fortran users should declare info as a double precision
2800    array of dimension MAT_INFO_SIZE, and then extract the parameters
2801    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2802    a complete list of parameter names.
2803 .vb
2804       double  precision info(MAT_INFO_SIZE)
2805       double  precision mal, nz_a
2806       Mat     A
2807       integer ierr
2808 
2809       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2810       mal = info(MAT_INFO_MALLOCS)
2811       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2812 .ve
2813 
2814     Level: intermediate
2815 
2816     Concepts: matrices^getting information on
2817 
2818     Developer Note: fortran interface is not autogenerated as the f90
2819     interface defintion cannot be generated correctly [due to MatInfo]
2820 
2821 .seealso: MatStashGetInfo()
2822 
2823 @*/
2824 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2825 {
2826   PetscErrorCode ierr;
2827 
2828   PetscFunctionBegin;
2829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2830   PetscValidType(mat,1);
2831   PetscValidPointer(info,3);
2832   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2833   MatCheckPreallocated(mat,1);
2834   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2835   PetscFunctionReturn(0);
2836 }
2837 
2838 /*
2839    This is used by external packages where it is not easy to get the info from the actual
2840    matrix factorization.
2841 */
2842 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2843 {
2844   PetscErrorCode ierr;
2845 
2846   PetscFunctionBegin;
2847   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2848   PetscFunctionReturn(0);
2849 }
2850 
2851 /* ----------------------------------------------------------*/
2852 
2853 /*@C
2854    MatLUFactor - Performs in-place LU factorization of matrix.
2855 
2856    Collective on Mat
2857 
2858    Input Parameters:
2859 +  mat - the matrix
2860 .  row - row permutation
2861 .  col - column permutation
2862 -  info - options for factorization, includes
2863 $          fill - expected fill as ratio of original fill.
2864 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2865 $                   Run with the option -info to determine an optimal value to use
2866 
2867    Notes:
2868    Most users should employ the simplified KSP interface for linear solvers
2869    instead of working directly with matrix algebra routines such as this.
2870    See, e.g., KSPCreate().
2871 
2872    This changes the state of the matrix to a factored matrix; it cannot be used
2873    for example with MatSetValues() unless one first calls MatSetUnfactored().
2874 
2875    Level: developer
2876 
2877    Concepts: matrices^LU factorization
2878 
2879 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2880           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2881 
2882     Developer Note: fortran interface is not autogenerated as the f90
2883     interface defintion cannot be generated correctly [due to MatFactorInfo]
2884 
2885 @*/
2886 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2887 {
2888   PetscErrorCode ierr;
2889   MatFactorInfo  tinfo;
2890 
2891   PetscFunctionBegin;
2892   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2893   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2894   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2895   if (info) PetscValidPointer(info,4);
2896   PetscValidType(mat,1);
2897   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2898   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2899   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2900   MatCheckPreallocated(mat,1);
2901   if (!info) {
2902     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2903     info = &tinfo;
2904   }
2905 
2906   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2907   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2908   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2909   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2910   PetscFunctionReturn(0);
2911 }
2912 
2913 /*@C
2914    MatILUFactor - Performs in-place ILU factorization of matrix.
2915 
2916    Collective on Mat
2917 
2918    Input Parameters:
2919 +  mat - the matrix
2920 .  row - row permutation
2921 .  col - column permutation
2922 -  info - structure containing
2923 $      levels - number of levels of fill.
2924 $      expected fill - as ratio of original fill.
2925 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2926                 missing diagonal entries)
2927 
2928    Notes:
2929    Probably really in-place only when level of fill is zero, otherwise allocates
2930    new space to store factored matrix and deletes previous memory.
2931 
2932    Most users should employ the simplified KSP interface for linear solvers
2933    instead of working directly with matrix algebra routines such as this.
2934    See, e.g., KSPCreate().
2935 
2936    Level: developer
2937 
2938    Concepts: matrices^ILU factorization
2939 
2940 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2941 
2942     Developer Note: fortran interface is not autogenerated as the f90
2943     interface defintion cannot be generated correctly [due to MatFactorInfo]
2944 
2945 @*/
2946 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2947 {
2948   PetscErrorCode ierr;
2949 
2950   PetscFunctionBegin;
2951   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2952   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2953   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2954   PetscValidPointer(info,4);
2955   PetscValidType(mat,1);
2956   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2957   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2958   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2959   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2960   MatCheckPreallocated(mat,1);
2961 
2962   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2963   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2964   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2965   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2966   PetscFunctionReturn(0);
2967 }
2968 
2969 /*@C
2970    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2971    Call this routine before calling MatLUFactorNumeric().
2972 
2973    Collective on Mat
2974 
2975    Input Parameters:
2976 +  fact - the factor matrix obtained with MatGetFactor()
2977 .  mat - the matrix
2978 .  row, col - row and column permutations
2979 -  info - options for factorization, includes
2980 $          fill - expected fill as ratio of original fill.
2981 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2982 $                   Run with the option -info to determine an optimal value to use
2983 
2984 
2985    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2986 
2987    Most users should employ the simplified KSP interface for linear solvers
2988    instead of working directly with matrix algebra routines such as this.
2989    See, e.g., KSPCreate().
2990 
2991    Level: developer
2992 
2993    Concepts: matrices^LU symbolic factorization
2994 
2995 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2996 
2997     Developer Note: fortran interface is not autogenerated as the f90
2998     interface defintion cannot be generated correctly [due to MatFactorInfo]
2999 
3000 @*/
3001 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3002 {
3003   PetscErrorCode ierr;
3004 
3005   PetscFunctionBegin;
3006   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3007   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3008   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3009   if (info) PetscValidPointer(info,4);
3010   PetscValidType(mat,1);
3011   PetscValidPointer(fact,5);
3012   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3013   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3014   if (!(fact)->ops->lufactorsymbolic) {
3015     const MatSolverPackage spackage;
3016     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
3017     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3018   }
3019   MatCheckPreallocated(mat,2);
3020 
3021   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3022   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3023   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3024   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3025   PetscFunctionReturn(0);
3026 }
3027 
3028 /*@C
3029    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3030    Call this routine after first calling MatLUFactorSymbolic().
3031 
3032    Collective on Mat
3033 
3034    Input Parameters:
3035 +  fact - the factor matrix obtained with MatGetFactor()
3036 .  mat - the matrix
3037 -  info - options for factorization
3038 
3039    Notes:
3040    See MatLUFactor() for in-place factorization.  See
3041    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3042 
3043    Most users should employ the simplified KSP interface for linear solvers
3044    instead of working directly with matrix algebra routines such as this.
3045    See, e.g., KSPCreate().
3046 
3047    Level: developer
3048 
3049    Concepts: matrices^LU numeric factorization
3050 
3051 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3052 
3053     Developer Note: fortran interface is not autogenerated as the f90
3054     interface defintion cannot be generated correctly [due to MatFactorInfo]
3055 
3056 @*/
3057 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3058 {
3059   PetscErrorCode ierr;
3060 
3061   PetscFunctionBegin;
3062   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3063   PetscValidType(mat,1);
3064   PetscValidPointer(fact,2);
3065   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3066   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3067   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3068 
3069   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3070   MatCheckPreallocated(mat,2);
3071   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3072   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3073   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3074   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3075   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3076   PetscFunctionReturn(0);
3077 }
3078 
3079 /*@C
3080    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3081    symmetric matrix.
3082 
3083    Collective on Mat
3084 
3085    Input Parameters:
3086 +  mat - the matrix
3087 .  perm - row and column permutations
3088 -  f - expected fill as ratio of original fill
3089 
3090    Notes:
3091    See MatLUFactor() for the nonsymmetric case.  See also
3092    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3093 
3094    Most users should employ the simplified KSP interface for linear solvers
3095    instead of working directly with matrix algebra routines such as this.
3096    See, e.g., KSPCreate().
3097 
3098    Level: developer
3099 
3100    Concepts: matrices^Cholesky factorization
3101 
3102 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3103           MatGetOrdering()
3104 
3105     Developer Note: fortran interface is not autogenerated as the f90
3106     interface defintion cannot be generated correctly [due to MatFactorInfo]
3107 
3108 @*/
3109 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3110 {
3111   PetscErrorCode ierr;
3112 
3113   PetscFunctionBegin;
3114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3115   PetscValidType(mat,1);
3116   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3117   if (info) PetscValidPointer(info,3);
3118   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3119   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3120   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3121   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3122   MatCheckPreallocated(mat,1);
3123 
3124   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3125   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3126   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3127   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3128   PetscFunctionReturn(0);
3129 }
3130 
3131 /*@C
3132    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3133    of a symmetric matrix.
3134 
3135    Collective on Mat
3136 
3137    Input Parameters:
3138 +  fact - the factor matrix obtained with MatGetFactor()
3139 .  mat - the matrix
3140 .  perm - row and column permutations
3141 -  info - options for factorization, includes
3142 $          fill - expected fill as ratio of original fill.
3143 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3144 $                   Run with the option -info to determine an optimal value to use
3145 
3146    Notes:
3147    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3148    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3149 
3150    Most users should employ the simplified KSP interface for linear solvers
3151    instead of working directly with matrix algebra routines such as this.
3152    See, e.g., KSPCreate().
3153 
3154    Level: developer
3155 
3156    Concepts: matrices^Cholesky symbolic factorization
3157 
3158 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3159           MatGetOrdering()
3160 
3161     Developer Note: fortran interface is not autogenerated as the f90
3162     interface defintion cannot be generated correctly [due to MatFactorInfo]
3163 
3164 @*/
3165 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3166 {
3167   PetscErrorCode ierr;
3168 
3169   PetscFunctionBegin;
3170   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3171   PetscValidType(mat,1);
3172   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3173   if (info) PetscValidPointer(info,3);
3174   PetscValidPointer(fact,4);
3175   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3176   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3177   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3178   if (!(fact)->ops->choleskyfactorsymbolic) {
3179     const MatSolverPackage spackage;
3180     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
3181     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3182   }
3183   MatCheckPreallocated(mat,2);
3184 
3185   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3186   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3187   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3188   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3189   PetscFunctionReturn(0);
3190 }
3191 
3192 /*@C
3193    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3194    of a symmetric matrix. Call this routine after first calling
3195    MatCholeskyFactorSymbolic().
3196 
3197    Collective on Mat
3198 
3199    Input Parameters:
3200 +  fact - the factor matrix obtained with MatGetFactor()
3201 .  mat - the initial matrix
3202 .  info - options for factorization
3203 -  fact - the symbolic factor of mat
3204 
3205 
3206    Notes:
3207    Most users should employ the simplified KSP interface for linear solvers
3208    instead of working directly with matrix algebra routines such as this.
3209    See, e.g., KSPCreate().
3210 
3211    Level: developer
3212 
3213    Concepts: matrices^Cholesky numeric factorization
3214 
3215 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3216 
3217     Developer Note: fortran interface is not autogenerated as the f90
3218     interface defintion cannot be generated correctly [due to MatFactorInfo]
3219 
3220 @*/
3221 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3222 {
3223   PetscErrorCode ierr;
3224 
3225   PetscFunctionBegin;
3226   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3227   PetscValidType(mat,1);
3228   PetscValidPointer(fact,2);
3229   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3230   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3231   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3232   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3233   MatCheckPreallocated(mat,2);
3234 
3235   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3236   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3237   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3238   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3239   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3240   PetscFunctionReturn(0);
3241 }
3242 
3243 /* ----------------------------------------------------------------*/
3244 /*@
3245    MatSolve - Solves A x = b, given a factored matrix.
3246 
3247    Neighbor-wise Collective on Mat and Vec
3248 
3249    Input Parameters:
3250 +  mat - the factored matrix
3251 -  b - the right-hand-side vector
3252 
3253    Output Parameter:
3254 .  x - the result vector
3255 
3256    Notes:
3257    The vectors b and x cannot be the same.  I.e., one cannot
3258    call MatSolve(A,x,x).
3259 
3260    Notes:
3261    Most users should employ the simplified KSP interface for linear solvers
3262    instead of working directly with matrix algebra routines such as this.
3263    See, e.g., KSPCreate().
3264 
3265    Level: developer
3266 
3267    Concepts: matrices^triangular solves
3268 
3269 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3270 @*/
3271 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3272 {
3273   PetscErrorCode ierr;
3274 
3275   PetscFunctionBegin;
3276   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3277   PetscValidType(mat,1);
3278   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3279   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3280   PetscCheckSameComm(mat,1,b,2);
3281   PetscCheckSameComm(mat,1,x,3);
3282   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3283   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3284   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3285   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3286   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3287   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3288   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3289   MatCheckPreallocated(mat,1);
3290 
3291   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3292   if (mat->factorerrortype) {
3293     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3294     ierr = VecSetInf(x);CHKERRQ(ierr);
3295   } else {
3296     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3297   }
3298   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3299   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3300   PetscFunctionReturn(0);
3301 }
3302 
3303 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3304 {
3305   PetscErrorCode ierr;
3306   Vec            b,x;
3307   PetscInt       m,N,i;
3308   PetscScalar    *bb,*xx;
3309   PetscBool      flg;
3310 
3311   PetscFunctionBegin;
3312   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3313   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3314   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3315   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3316 
3317   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3318   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3319   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3320   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3321   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3322   for (i=0; i<N; i++) {
3323     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3324     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3325     if (trans) {
3326       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3327     } else {
3328       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3329     }
3330     ierr = VecResetArray(x);CHKERRQ(ierr);
3331     ierr = VecResetArray(b);CHKERRQ(ierr);
3332   }
3333   ierr = VecDestroy(&b);CHKERRQ(ierr);
3334   ierr = VecDestroy(&x);CHKERRQ(ierr);
3335   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3336   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3337   PetscFunctionReturn(0);
3338 }
3339 
3340 /*@
3341    MatMatSolve - Solves A X = B, given a factored matrix.
3342 
3343    Neighbor-wise Collective on Mat
3344 
3345    Input Parameters:
3346 +  A - the factored matrix
3347 -  B - the right-hand-side matrix  (dense matrix)
3348 
3349    Output Parameter:
3350 .  X - the result matrix (dense matrix)
3351 
3352    Notes:
3353    The matrices b and x cannot be the same.  I.e., one cannot
3354    call MatMatSolve(A,x,x).
3355 
3356    Notes:
3357    Most users should usually employ the simplified KSP interface for linear solvers
3358    instead of working directly with matrix algebra routines such as this.
3359    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3360    at a time.
3361 
3362    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3363    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3364 
3365    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3366 
3367    Level: developer
3368 
3369    Concepts: matrices^triangular solves
3370 
3371 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3372 @*/
3373 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3374 {
3375   PetscErrorCode ierr;
3376 
3377   PetscFunctionBegin;
3378   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3379   PetscValidType(A,1);
3380   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3381   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3382   PetscCheckSameComm(A,1,B,2);
3383   PetscCheckSameComm(A,1,X,3);
3384   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3385   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3386   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3387   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3388   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3389   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3390   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3391   MatCheckPreallocated(A,1);
3392 
3393   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3394   if (!A->ops->matsolve) {
3395     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3396     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3397   } else {
3398     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3399   }
3400   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3401   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3402   PetscFunctionReturn(0);
3403 }
3404 
3405 /*@
3406    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3407 
3408    Neighbor-wise Collective on Mat
3409 
3410    Input Parameters:
3411 +  A - the factored matrix
3412 -  B - the right-hand-side matrix  (dense matrix)
3413 
3414    Output Parameter:
3415 .  X - the result matrix (dense matrix)
3416 
3417    Notes:
3418    The matrices b and x cannot be the same.  I.e., one cannot
3419    call MatMatSolveTranspose(A,x,x).
3420 
3421    Notes:
3422    Most users should usually employ the simplified KSP interface for linear solvers
3423    instead of working directly with matrix algebra routines such as this.
3424    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3425    at a time.
3426 
3427    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3428    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3429 
3430    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3431 
3432    Level: developer
3433 
3434    Concepts: matrices^triangular solves
3435 
3436 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3437 @*/
3438 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3439 {
3440   PetscErrorCode ierr;
3441 
3442   PetscFunctionBegin;
3443   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3444   PetscValidType(A,1);
3445   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3446   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3447   PetscCheckSameComm(A,1,B,2);
3448   PetscCheckSameComm(A,1,X,3);
3449   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3450   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3451   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3452   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3453   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3454   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3455   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3456   MatCheckPreallocated(A,1);
3457 
3458   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3459   if (!A->ops->matsolvetranspose) {
3460     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3461     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3462   } else {
3463     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3464   }
3465   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3466   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3467   PetscFunctionReturn(0);
3468 }
3469 
3470 /*@
3471    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3472                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3473 
3474    Neighbor-wise Collective on Mat and Vec
3475 
3476    Input Parameters:
3477 +  mat - the factored matrix
3478 -  b - the right-hand-side vector
3479 
3480    Output Parameter:
3481 .  x - the result vector
3482 
3483    Notes:
3484    MatSolve() should be used for most applications, as it performs
3485    a forward solve followed by a backward solve.
3486 
3487    The vectors b and x cannot be the same,  i.e., one cannot
3488    call MatForwardSolve(A,x,x).
3489 
3490    For matrix in seqsbaij format with block size larger than 1,
3491    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3492    MatForwardSolve() solves U^T*D y = b, and
3493    MatBackwardSolve() solves U x = y.
3494    Thus they do not provide a symmetric preconditioner.
3495 
3496    Most users should employ the simplified KSP interface for linear solvers
3497    instead of working directly with matrix algebra routines such as this.
3498    See, e.g., KSPCreate().
3499 
3500    Level: developer
3501 
3502    Concepts: matrices^forward solves
3503 
3504 .seealso: MatSolve(), MatBackwardSolve()
3505 @*/
3506 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3507 {
3508   PetscErrorCode ierr;
3509 
3510   PetscFunctionBegin;
3511   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3512   PetscValidType(mat,1);
3513   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3514   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3515   PetscCheckSameComm(mat,1,b,2);
3516   PetscCheckSameComm(mat,1,x,3);
3517   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3518   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3519   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3520   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3521   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3522   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3523   MatCheckPreallocated(mat,1);
3524   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3525   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3526   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3527   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3528   PetscFunctionReturn(0);
3529 }
3530 
3531 /*@
3532    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3533                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3534 
3535    Neighbor-wise Collective on Mat and Vec
3536 
3537    Input Parameters:
3538 +  mat - the factored matrix
3539 -  b - the right-hand-side vector
3540 
3541    Output Parameter:
3542 .  x - the result vector
3543 
3544    Notes:
3545    MatSolve() should be used for most applications, as it performs
3546    a forward solve followed by a backward solve.
3547 
3548    The vectors b and x cannot be the same.  I.e., one cannot
3549    call MatBackwardSolve(A,x,x).
3550 
3551    For matrix in seqsbaij format with block size larger than 1,
3552    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3553    MatForwardSolve() solves U^T*D y = b, and
3554    MatBackwardSolve() solves U x = y.
3555    Thus they do not provide a symmetric preconditioner.
3556 
3557    Most users should employ the simplified KSP interface for linear solvers
3558    instead of working directly with matrix algebra routines such as this.
3559    See, e.g., KSPCreate().
3560 
3561    Level: developer
3562 
3563    Concepts: matrices^backward solves
3564 
3565 .seealso: MatSolve(), MatForwardSolve()
3566 @*/
3567 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3568 {
3569   PetscErrorCode ierr;
3570 
3571   PetscFunctionBegin;
3572   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3573   PetscValidType(mat,1);
3574   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3575   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3576   PetscCheckSameComm(mat,1,b,2);
3577   PetscCheckSameComm(mat,1,x,3);
3578   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3579   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3581   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3582   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3583   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3584   MatCheckPreallocated(mat,1);
3585 
3586   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3587   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3588   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3589   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3590   PetscFunctionReturn(0);
3591 }
3592 
3593 /*@
3594    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3595 
3596    Neighbor-wise Collective on Mat and Vec
3597 
3598    Input Parameters:
3599 +  mat - the factored matrix
3600 .  b - the right-hand-side vector
3601 -  y - the vector to be added to
3602 
3603    Output Parameter:
3604 .  x - the result vector
3605 
3606    Notes:
3607    The vectors b and x cannot be the same.  I.e., one cannot
3608    call MatSolveAdd(A,x,y,x).
3609 
3610    Most users should employ the simplified KSP interface for linear solvers
3611    instead of working directly with matrix algebra routines such as this.
3612    See, e.g., KSPCreate().
3613 
3614    Level: developer
3615 
3616    Concepts: matrices^triangular solves
3617 
3618 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3619 @*/
3620 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3621 {
3622   PetscScalar    one = 1.0;
3623   Vec            tmp;
3624   PetscErrorCode ierr;
3625 
3626   PetscFunctionBegin;
3627   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3628   PetscValidType(mat,1);
3629   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3630   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3631   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3632   PetscCheckSameComm(mat,1,b,2);
3633   PetscCheckSameComm(mat,1,y,2);
3634   PetscCheckSameComm(mat,1,x,3);
3635   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3636   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3637   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3638   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3639   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3640   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3641   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3642   MatCheckPreallocated(mat,1);
3643 
3644   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3645   if (mat->ops->solveadd) {
3646     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3647   } else {
3648     /* do the solve then the add manually */
3649     if (x != y) {
3650       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3651       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3652     } else {
3653       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3654       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3655       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3656       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3657       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3658       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3659     }
3660   }
3661   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3662   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3663   PetscFunctionReturn(0);
3664 }
3665 
3666 /*@
3667    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3668 
3669    Neighbor-wise Collective on Mat and Vec
3670 
3671    Input Parameters:
3672 +  mat - the factored matrix
3673 -  b - the right-hand-side vector
3674 
3675    Output Parameter:
3676 .  x - the result vector
3677 
3678    Notes:
3679    The vectors b and x cannot be the same.  I.e., one cannot
3680    call MatSolveTranspose(A,x,x).
3681 
3682    Most users should employ the simplified KSP interface for linear solvers
3683    instead of working directly with matrix algebra routines such as this.
3684    See, e.g., KSPCreate().
3685 
3686    Level: developer
3687 
3688    Concepts: matrices^triangular solves
3689 
3690 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3691 @*/
3692 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3693 {
3694   PetscErrorCode ierr;
3695 
3696   PetscFunctionBegin;
3697   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3698   PetscValidType(mat,1);
3699   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3700   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3701   PetscCheckSameComm(mat,1,b,2);
3702   PetscCheckSameComm(mat,1,x,3);
3703   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3704   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3705   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3706   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3707   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3708   MatCheckPreallocated(mat,1);
3709   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3710   if (mat->factorerrortype) {
3711     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3712     ierr = VecSetInf(x);CHKERRQ(ierr);
3713   } else {
3714     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3715   }
3716   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3717   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3718   PetscFunctionReturn(0);
3719 }
3720 
3721 /*@
3722    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3723                       factored matrix.
3724 
3725    Neighbor-wise Collective on Mat and Vec
3726 
3727    Input Parameters:
3728 +  mat - the factored matrix
3729 .  b - the right-hand-side vector
3730 -  y - the vector to be added to
3731 
3732    Output Parameter:
3733 .  x - the result vector
3734 
3735    Notes:
3736    The vectors b and x cannot be the same.  I.e., one cannot
3737    call MatSolveTransposeAdd(A,x,y,x).
3738 
3739    Most users should employ the simplified KSP interface for linear solvers
3740    instead of working directly with matrix algebra routines such as this.
3741    See, e.g., KSPCreate().
3742 
3743    Level: developer
3744 
3745    Concepts: matrices^triangular solves
3746 
3747 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3748 @*/
3749 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3750 {
3751   PetscScalar    one = 1.0;
3752   PetscErrorCode ierr;
3753   Vec            tmp;
3754 
3755   PetscFunctionBegin;
3756   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3757   PetscValidType(mat,1);
3758   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3759   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3760   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3761   PetscCheckSameComm(mat,1,b,2);
3762   PetscCheckSameComm(mat,1,y,3);
3763   PetscCheckSameComm(mat,1,x,4);
3764   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3765   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3766   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3767   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3768   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3769   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3770   MatCheckPreallocated(mat,1);
3771 
3772   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3773   if (mat->ops->solvetransposeadd) {
3774     if (mat->factorerrortype) {
3775       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3776       ierr = VecSetInf(x);CHKERRQ(ierr);
3777     } else {
3778       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3779     }
3780   } else {
3781     /* do the solve then the add manually */
3782     if (x != y) {
3783       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3784       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3785     } else {
3786       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3787       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3788       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3789       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3790       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3791       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3792     }
3793   }
3794   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3795   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3796   PetscFunctionReturn(0);
3797 }
3798 /* ----------------------------------------------------------------*/
3799 
3800 /*@
3801    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3802 
3803    Neighbor-wise Collective on Mat and Vec
3804 
3805    Input Parameters:
3806 +  mat - the matrix
3807 .  b - the right hand side
3808 .  omega - the relaxation factor
3809 .  flag - flag indicating the type of SOR (see below)
3810 .  shift -  diagonal shift
3811 .  its - the number of iterations
3812 -  lits - the number of local iterations
3813 
3814    Output Parameters:
3815 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3816 
3817    SOR Flags:
3818 .     SOR_FORWARD_SWEEP - forward SOR
3819 .     SOR_BACKWARD_SWEEP - backward SOR
3820 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3821 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3822 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3823 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3824 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3825          upper/lower triangular part of matrix to
3826          vector (with omega)
3827 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3828 
3829    Notes:
3830    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3831    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3832    on each processor.
3833 
3834    Application programmers will not generally use MatSOR() directly,
3835    but instead will employ the KSP/PC interface.
3836 
3837    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3838 
3839    Notes for Advanced Users:
3840    The flags are implemented as bitwise inclusive or operations.
3841    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3842    to specify a zero initial guess for SSOR.
3843 
3844    Most users should employ the simplified KSP interface for linear solvers
3845    instead of working directly with matrix algebra routines such as this.
3846    See, e.g., KSPCreate().
3847 
3848    Vectors x and b CANNOT be the same
3849 
3850    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3851 
3852    Level: developer
3853 
3854    Concepts: matrices^relaxation
3855    Concepts: matrices^SOR
3856    Concepts: matrices^Gauss-Seidel
3857 
3858 @*/
3859 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3860 {
3861   PetscErrorCode ierr;
3862 
3863   PetscFunctionBegin;
3864   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3865   PetscValidType(mat,1);
3866   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3867   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3868   PetscCheckSameComm(mat,1,b,2);
3869   PetscCheckSameComm(mat,1,x,8);
3870   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3871   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3872   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3873   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3874   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3875   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3876   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3877   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3878   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3879 
3880   MatCheckPreallocated(mat,1);
3881   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3882   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3883   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3884   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3885   PetscFunctionReturn(0);
3886 }
3887 
3888 /*
3889       Default matrix copy routine.
3890 */
3891 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3892 {
3893   PetscErrorCode    ierr;
3894   PetscInt          i,rstart = 0,rend = 0,nz;
3895   const PetscInt    *cwork;
3896   const PetscScalar *vwork;
3897 
3898   PetscFunctionBegin;
3899   if (B->assembled) {
3900     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3901   }
3902   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3903   for (i=rstart; i<rend; i++) {
3904     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3905     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3906     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3907   }
3908   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3909   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3910   PetscFunctionReturn(0);
3911 }
3912 
3913 /*@
3914    MatCopy - Copys a matrix to another matrix.
3915 
3916    Collective on Mat
3917 
3918    Input Parameters:
3919 +  A - the matrix
3920 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3921 
3922    Output Parameter:
3923 .  B - where the copy is put
3924 
3925    Notes:
3926    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3927    same nonzero pattern or the routine will crash.
3928 
3929    MatCopy() copies the matrix entries of a matrix to another existing
3930    matrix (after first zeroing the second matrix).  A related routine is
3931    MatConvert(), which first creates a new matrix and then copies the data.
3932 
3933    Level: intermediate
3934 
3935    Concepts: matrices^copying
3936 
3937 .seealso: MatConvert(), MatDuplicate()
3938 
3939 @*/
3940 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3941 {
3942   PetscErrorCode ierr;
3943   PetscInt       i;
3944 
3945   PetscFunctionBegin;
3946   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3947   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3948   PetscValidType(A,1);
3949   PetscValidType(B,2);
3950   PetscCheckSameComm(A,1,B,2);
3951   MatCheckPreallocated(B,2);
3952   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3953   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3954   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3955   MatCheckPreallocated(A,1);
3956 
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,NULL,&ones);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: You CANNOT change any of the ia[] or ja[] values.
7336 
7337            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7338 
7339     Fortran Node
7340 
7341            In Fortran use
7342 $           PetscInt ia(1), ja(1)
7343 $           PetscOffset iia, jja
7344 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7345 $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7346 $
7347 $          or
7348 $
7349 $           PetscInt, pointer :: ia(:),ja(:)
7350 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7351 $      Acess the ith and jth entries via ia(i) and ja(j)
7352 
7353 
7354 
7355 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7356 @*/
7357 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7358 {
7359   PetscErrorCode ierr;
7360 
7361   PetscFunctionBegin;
7362   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7363   PetscValidType(mat,1);
7364   PetscValidIntPointer(n,5);
7365   if (ia) PetscValidIntPointer(ia,6);
7366   if (ja) PetscValidIntPointer(ja,7);
7367   PetscValidIntPointer(done,8);
7368   MatCheckPreallocated(mat,1);
7369   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7370   else {
7371     *done = PETSC_TRUE;
7372     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7373     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7374     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7375   }
7376   PetscFunctionReturn(0);
7377 }
7378 
7379 /*@C
7380     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7381 
7382     Collective on Mat
7383 
7384     Input Parameters:
7385 +   mat - the matrix
7386 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7387 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7388                 symmetrized
7389 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7390                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7391                  always used.
7392 .   n - number of columns in the (possibly compressed) matrix
7393 .   ia - the column pointers
7394 -   ja - the row indices
7395 
7396     Output Parameters:
7397 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7398 
7399     Note:
7400     This routine zeros out n, ia, and ja. This is to prevent accidental
7401     us of the array after it has been restored. If you pass NULL, it will
7402     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7403 
7404     Level: developer
7405 
7406 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7407 @*/
7408 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7409 {
7410   PetscErrorCode ierr;
7411 
7412   PetscFunctionBegin;
7413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7414   PetscValidType(mat,1);
7415   PetscValidIntPointer(n,4);
7416   if (ia) PetscValidIntPointer(ia,5);
7417   if (ja) PetscValidIntPointer(ja,6);
7418   PetscValidIntPointer(done,7);
7419   MatCheckPreallocated(mat,1);
7420   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7421   else {
7422     *done = PETSC_TRUE;
7423     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7424   }
7425   PetscFunctionReturn(0);
7426 }
7427 
7428 /*@C
7429     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7430     MatGetRowIJ().
7431 
7432     Collective on Mat
7433 
7434     Input Parameters:
7435 +   mat - the matrix
7436 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7437 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7438                 symmetrized
7439 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7440                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7441                  always used.
7442 .   n - size of (possibly compressed) matrix
7443 .   ia - the row pointers
7444 -   ja - the column indices
7445 
7446     Output Parameters:
7447 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7448 
7449     Note:
7450     This routine zeros out n, ia, and ja. This is to prevent accidental
7451     us of the array after it has been restored. If you pass NULL, it will
7452     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7453 
7454     Level: developer
7455 
7456 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7457 @*/
7458 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7459 {
7460   PetscErrorCode ierr;
7461 
7462   PetscFunctionBegin;
7463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7464   PetscValidType(mat,1);
7465   if (ia) PetscValidIntPointer(ia,6);
7466   if (ja) PetscValidIntPointer(ja,7);
7467   PetscValidIntPointer(done,8);
7468   MatCheckPreallocated(mat,1);
7469 
7470   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7471   else {
7472     *done = PETSC_TRUE;
7473     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7474     if (n)  *n = 0;
7475     if (ia) *ia = NULL;
7476     if (ja) *ja = NULL;
7477   }
7478   PetscFunctionReturn(0);
7479 }
7480 
7481 /*@C
7482     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7483     MatGetColumnIJ().
7484 
7485     Collective on Mat
7486 
7487     Input Parameters:
7488 +   mat - the matrix
7489 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7490 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7491                 symmetrized
7492 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7493                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7494                  always used.
7495 
7496     Output Parameters:
7497 +   n - size of (possibly compressed) matrix
7498 .   ia - the column pointers
7499 .   ja - the row indices
7500 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7501 
7502     Level: developer
7503 
7504 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7505 @*/
7506 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7507 {
7508   PetscErrorCode ierr;
7509 
7510   PetscFunctionBegin;
7511   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7512   PetscValidType(mat,1);
7513   if (ia) PetscValidIntPointer(ia,5);
7514   if (ja) PetscValidIntPointer(ja,6);
7515   PetscValidIntPointer(done,7);
7516   MatCheckPreallocated(mat,1);
7517 
7518   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7519   else {
7520     *done = PETSC_TRUE;
7521     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7522     if (n)  *n = 0;
7523     if (ia) *ia = NULL;
7524     if (ja) *ja = NULL;
7525   }
7526   PetscFunctionReturn(0);
7527 }
7528 
7529 /*@C
7530     MatColoringPatch -Used inside matrix coloring routines that
7531     use MatGetRowIJ() and/or MatGetColumnIJ().
7532 
7533     Collective on Mat
7534 
7535     Input Parameters:
7536 +   mat - the matrix
7537 .   ncolors - max color value
7538 .   n   - number of entries in colorarray
7539 -   colorarray - array indicating color for each column
7540 
7541     Output Parameters:
7542 .   iscoloring - coloring generated using colorarray information
7543 
7544     Level: developer
7545 
7546 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7547 
7548 @*/
7549 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7550 {
7551   PetscErrorCode ierr;
7552 
7553   PetscFunctionBegin;
7554   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7555   PetscValidType(mat,1);
7556   PetscValidIntPointer(colorarray,4);
7557   PetscValidPointer(iscoloring,5);
7558   MatCheckPreallocated(mat,1);
7559 
7560   if (!mat->ops->coloringpatch) {
7561     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7562   } else {
7563     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7564   }
7565   PetscFunctionReturn(0);
7566 }
7567 
7568 
7569 /*@
7570    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7571 
7572    Logically Collective on Mat
7573 
7574    Input Parameter:
7575 .  mat - the factored matrix to be reset
7576 
7577    Notes:
7578    This routine should be used only with factored matrices formed by in-place
7579    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7580    format).  This option can save memory, for example, when solving nonlinear
7581    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7582    ILU(0) preconditioner.
7583 
7584    Note that one can specify in-place ILU(0) factorization by calling
7585 .vb
7586      PCType(pc,PCILU);
7587      PCFactorSeUseInPlace(pc);
7588 .ve
7589    or by using the options -pc_type ilu -pc_factor_in_place
7590 
7591    In-place factorization ILU(0) can also be used as a local
7592    solver for the blocks within the block Jacobi or additive Schwarz
7593    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7594    for details on setting local solver options.
7595 
7596    Most users should employ the simplified KSP interface for linear solvers
7597    instead of working directly with matrix algebra routines such as this.
7598    See, e.g., KSPCreate().
7599 
7600    Level: developer
7601 
7602 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7603 
7604    Concepts: matrices^unfactored
7605 
7606 @*/
7607 PetscErrorCode MatSetUnfactored(Mat mat)
7608 {
7609   PetscErrorCode ierr;
7610 
7611   PetscFunctionBegin;
7612   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7613   PetscValidType(mat,1);
7614   MatCheckPreallocated(mat,1);
7615   mat->factortype = MAT_FACTOR_NONE;
7616   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7617   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7618   PetscFunctionReturn(0);
7619 }
7620 
7621 /*MC
7622     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7623 
7624     Synopsis:
7625     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7626 
7627     Not collective
7628 
7629     Input Parameter:
7630 .   x - matrix
7631 
7632     Output Parameters:
7633 +   xx_v - the Fortran90 pointer to the array
7634 -   ierr - error code
7635 
7636     Example of Usage:
7637 .vb
7638       PetscScalar, pointer xx_v(:,:)
7639       ....
7640       call MatDenseGetArrayF90(x,xx_v,ierr)
7641       a = xx_v(3)
7642       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7643 .ve
7644 
7645     Level: advanced
7646 
7647 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7648 
7649     Concepts: matrices^accessing array
7650 
7651 M*/
7652 
7653 /*MC
7654     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7655     accessed with MatDenseGetArrayF90().
7656 
7657     Synopsis:
7658     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7659 
7660     Not collective
7661 
7662     Input Parameters:
7663 +   x - matrix
7664 -   xx_v - the Fortran90 pointer to the array
7665 
7666     Output Parameter:
7667 .   ierr - error code
7668 
7669     Example of Usage:
7670 .vb
7671        PetscScalar, pointer xx_v(:,:)
7672        ....
7673        call MatDenseGetArrayF90(x,xx_v,ierr)
7674        a = xx_v(3)
7675        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7676 .ve
7677 
7678     Level: advanced
7679 
7680 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7681 
7682 M*/
7683 
7684 
7685 /*MC
7686     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7687 
7688     Synopsis:
7689     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7690 
7691     Not collective
7692 
7693     Input Parameter:
7694 .   x - matrix
7695 
7696     Output Parameters:
7697 +   xx_v - the Fortran90 pointer to the array
7698 -   ierr - error code
7699 
7700     Example of Usage:
7701 .vb
7702       PetscScalar, pointer xx_v(:)
7703       ....
7704       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7705       a = xx_v(3)
7706       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7707 .ve
7708 
7709     Level: advanced
7710 
7711 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7712 
7713     Concepts: matrices^accessing array
7714 
7715 M*/
7716 
7717 /*MC
7718     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7719     accessed with MatSeqAIJGetArrayF90().
7720 
7721     Synopsis:
7722     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7723 
7724     Not collective
7725 
7726     Input Parameters:
7727 +   x - matrix
7728 -   xx_v - the Fortran90 pointer to the array
7729 
7730     Output Parameter:
7731 .   ierr - error code
7732 
7733     Example of Usage:
7734 .vb
7735        PetscScalar, pointer xx_v(:)
7736        ....
7737        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7738        a = xx_v(3)
7739        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7740 .ve
7741 
7742     Level: advanced
7743 
7744 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7745 
7746 M*/
7747 
7748 
7749 /*@
7750     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7751                       as the original matrix.
7752 
7753     Collective on Mat
7754 
7755     Input Parameters:
7756 +   mat - the original matrix
7757 .   isrow - parallel IS containing the rows this processor should obtain
7758 .   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.
7759 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7760 
7761     Output Parameter:
7762 .   newmat - the new submatrix, of the same type as the old
7763 
7764     Level: advanced
7765 
7766     Notes:
7767     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7768 
7769     Some matrix types place restrictions on the row and column indices, such
7770     as that they be sorted or that they be equal to each other.
7771 
7772     The index sets may not have duplicate entries.
7773 
7774       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7775    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7776    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7777    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7778    you are finished using it.
7779 
7780     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7781     the input matrix.
7782 
7783     If iscol is NULL then all columns are obtained (not supported in Fortran).
7784 
7785    Example usage:
7786    Consider the following 8x8 matrix with 34 non-zero values, that is
7787    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7788    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7789    as follows:
7790 
7791 .vb
7792             1  2  0  |  0  3  0  |  0  4
7793     Proc0   0  5  6  |  7  0  0  |  8  0
7794             9  0 10  | 11  0  0  | 12  0
7795     -------------------------------------
7796            13  0 14  | 15 16 17  |  0  0
7797     Proc1   0 18  0  | 19 20 21  |  0  0
7798             0  0  0  | 22 23  0  | 24  0
7799     -------------------------------------
7800     Proc2  25 26 27  |  0  0 28  | 29  0
7801            30  0  0  | 31 32 33  |  0 34
7802 .ve
7803 
7804     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7805 
7806 .vb
7807             2  0  |  0  3  0  |  0
7808     Proc0   5  6  |  7  0  0  |  8
7809     -------------------------------
7810     Proc1  18  0  | 19 20 21  |  0
7811     -------------------------------
7812     Proc2  26 27  |  0  0 28  | 29
7813             0  0  | 31 32 33  |  0
7814 .ve
7815 
7816 
7817     Concepts: matrices^submatrices
7818 
7819 .seealso: MatCreateSubMatrices()
7820 @*/
7821 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7822 {
7823   PetscErrorCode ierr;
7824   PetscMPIInt    size;
7825   Mat            *local;
7826   IS             iscoltmp;
7827 
7828   PetscFunctionBegin;
7829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7830   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7831   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7832   PetscValidPointer(newmat,5);
7833   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7834   PetscValidType(mat,1);
7835   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7836   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7837 
7838   MatCheckPreallocated(mat,1);
7839   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7840 
7841   if (!iscol || isrow == iscol) {
7842     PetscBool   stride;
7843     PetscMPIInt grabentirematrix = 0,grab;
7844     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7845     if (stride) {
7846       PetscInt first,step,n,rstart,rend;
7847       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7848       if (step == 1) {
7849         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7850         if (rstart == first) {
7851           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7852           if (n == rend-rstart) {
7853             grabentirematrix = 1;
7854           }
7855         }
7856       }
7857     }
7858     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7859     if (grab) {
7860       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7861       if (cll == MAT_INITIAL_MATRIX) {
7862         *newmat = mat;
7863         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7864       }
7865       PetscFunctionReturn(0);
7866     }
7867   }
7868 
7869   if (!iscol) {
7870     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7871   } else {
7872     iscoltmp = iscol;
7873   }
7874 
7875   /* if original matrix is on just one processor then use submatrix generated */
7876   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7877     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7878     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7879     PetscFunctionReturn(0);
7880   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7881     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7882     *newmat = *local;
7883     ierr    = PetscFree(local);CHKERRQ(ierr);
7884     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7885     PetscFunctionReturn(0);
7886   } else if (!mat->ops->createsubmatrix) {
7887     /* Create a new matrix type that implements the operation using the full matrix */
7888     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7889     switch (cll) {
7890     case MAT_INITIAL_MATRIX:
7891       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7892       break;
7893     case MAT_REUSE_MATRIX:
7894       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7895       break;
7896     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7897     }
7898     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7899     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7900     PetscFunctionReturn(0);
7901   }
7902 
7903   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7904   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7905   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7906   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7907   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7908   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7909   PetscFunctionReturn(0);
7910 }
7911 
7912 /*@
7913    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7914    used during the assembly process to store values that belong to
7915    other processors.
7916 
7917    Not Collective
7918 
7919    Input Parameters:
7920 +  mat   - the matrix
7921 .  size  - the initial size of the stash.
7922 -  bsize - the initial size of the block-stash(if used).
7923 
7924    Options Database Keys:
7925 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7926 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7927 
7928    Level: intermediate
7929 
7930    Notes:
7931      The block-stash is used for values set with MatSetValuesBlocked() while
7932      the stash is used for values set with MatSetValues()
7933 
7934      Run with the option -info and look for output of the form
7935      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7936      to determine the appropriate value, MM, to use for size and
7937      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7938      to determine the value, BMM to use for bsize
7939 
7940    Concepts: stash^setting matrix size
7941    Concepts: matrices^stash
7942 
7943 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7944 
7945 @*/
7946 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7947 {
7948   PetscErrorCode ierr;
7949 
7950   PetscFunctionBegin;
7951   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7952   PetscValidType(mat,1);
7953   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7954   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7955   PetscFunctionReturn(0);
7956 }
7957 
7958 /*@
7959    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7960      the matrix
7961 
7962    Neighbor-wise Collective on Mat
7963 
7964    Input Parameters:
7965 +  mat   - the matrix
7966 .  x,y - the vectors
7967 -  w - where the result is stored
7968 
7969    Level: intermediate
7970 
7971    Notes:
7972     w may be the same vector as y.
7973 
7974     This allows one to use either the restriction or interpolation (its transpose)
7975     matrix to do the interpolation
7976 
7977     Concepts: interpolation
7978 
7979 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7980 
7981 @*/
7982 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7983 {
7984   PetscErrorCode ierr;
7985   PetscInt       M,N,Ny;
7986 
7987   PetscFunctionBegin;
7988   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7989   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7990   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7991   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7992   PetscValidType(A,1);
7993   MatCheckPreallocated(A,1);
7994   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7995   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7996   if (M == Ny) {
7997     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7998   } else {
7999     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8000   }
8001   PetscFunctionReturn(0);
8002 }
8003 
8004 /*@
8005    MatInterpolate - y = A*x or A'*x depending on the shape of
8006      the matrix
8007 
8008    Neighbor-wise Collective on Mat
8009 
8010    Input Parameters:
8011 +  mat   - the matrix
8012 -  x,y - the vectors
8013 
8014    Level: intermediate
8015 
8016    Notes:
8017     This allows one to use either the restriction or interpolation (its transpose)
8018     matrix to do the interpolation
8019 
8020    Concepts: matrices^interpolation
8021 
8022 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8023 
8024 @*/
8025 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8026 {
8027   PetscErrorCode ierr;
8028   PetscInt       M,N,Ny;
8029 
8030   PetscFunctionBegin;
8031   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8032   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8033   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8034   PetscValidType(A,1);
8035   MatCheckPreallocated(A,1);
8036   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8037   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8038   if (M == Ny) {
8039     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8040   } else {
8041     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8042   }
8043   PetscFunctionReturn(0);
8044 }
8045 
8046 /*@
8047    MatRestrict - y = A*x or A'*x
8048 
8049    Neighbor-wise Collective on Mat
8050 
8051    Input Parameters:
8052 +  mat   - the matrix
8053 -  x,y - the vectors
8054 
8055    Level: intermediate
8056 
8057    Notes:
8058     This allows one to use either the restriction or interpolation (its transpose)
8059     matrix to do the restriction
8060 
8061    Concepts: matrices^restriction
8062 
8063 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8064 
8065 @*/
8066 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8067 {
8068   PetscErrorCode ierr;
8069   PetscInt       M,N,Ny;
8070 
8071   PetscFunctionBegin;
8072   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8073   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8074   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8075   PetscValidType(A,1);
8076   MatCheckPreallocated(A,1);
8077 
8078   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8079   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8080   if (M == Ny) {
8081     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8082   } else {
8083     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8084   }
8085   PetscFunctionReturn(0);
8086 }
8087 
8088 /*@
8089    MatGetNullSpace - retrieves the null space to a matrix.
8090 
8091    Logically Collective on Mat and MatNullSpace
8092 
8093    Input Parameters:
8094 +  mat - the matrix
8095 -  nullsp - the null space object
8096 
8097    Level: developer
8098 
8099    Concepts: null space^attaching to matrix
8100 
8101 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8102 @*/
8103 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8104 {
8105   PetscFunctionBegin;
8106   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8107   PetscValidType(mat,1);
8108   PetscValidPointer(nullsp,2);
8109   *nullsp = mat->nullsp;
8110   PetscFunctionReturn(0);
8111 }
8112 
8113 /*@
8114    MatSetNullSpace - attaches a null space to a matrix.
8115 
8116    Logically Collective on Mat and MatNullSpace
8117 
8118    Input Parameters:
8119 +  mat - the matrix
8120 -  nullsp - the null space object
8121 
8122    Level: advanced
8123 
8124    Notes:
8125       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8126 
8127       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8128       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8129 
8130       You can remove the null space by calling this routine with an nullsp of NULL
8131 
8132 
8133       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8134    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).
8135    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
8136    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
8137    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).
8138 
8139       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8140 
8141     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
8142     routine also automatically calls MatSetTransposeNullSpace().
8143 
8144    Concepts: null space^attaching to matrix
8145 
8146 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8147 @*/
8148 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8149 {
8150   PetscErrorCode ierr;
8151 
8152   PetscFunctionBegin;
8153   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8154   PetscValidType(mat,1);
8155   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8156   MatCheckPreallocated(mat,1);
8157   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8158   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8159   mat->nullsp = nullsp;
8160   if (mat->symmetric_set && mat->symmetric) {
8161     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8162   }
8163   PetscFunctionReturn(0);
8164 }
8165 
8166 /*@
8167    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8168 
8169    Logically Collective on Mat and MatNullSpace
8170 
8171    Input Parameters:
8172 +  mat - the matrix
8173 -  nullsp - the null space object
8174 
8175    Level: developer
8176 
8177    Concepts: null space^attaching to matrix
8178 
8179 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8180 @*/
8181 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8182 {
8183   PetscFunctionBegin;
8184   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8185   PetscValidType(mat,1);
8186   PetscValidPointer(nullsp,2);
8187   *nullsp = mat->transnullsp;
8188   PetscFunctionReturn(0);
8189 }
8190 
8191 /*@
8192    MatSetTransposeNullSpace - attaches a null space to a matrix.
8193 
8194    Logically Collective on Mat and MatNullSpace
8195 
8196    Input Parameters:
8197 +  mat - the matrix
8198 -  nullsp - the null space object
8199 
8200    Level: advanced
8201 
8202    Notes:
8203       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.
8204       You must also call MatSetNullSpace()
8205 
8206 
8207       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8208    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).
8209    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
8210    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
8211    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).
8212 
8213       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8214 
8215    Concepts: null space^attaching to matrix
8216 
8217 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8218 @*/
8219 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8220 {
8221   PetscErrorCode ierr;
8222 
8223   PetscFunctionBegin;
8224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8225   PetscValidType(mat,1);
8226   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8227   MatCheckPreallocated(mat,1);
8228   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8229   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8230   mat->transnullsp = nullsp;
8231   PetscFunctionReturn(0);
8232 }
8233 
8234 /*@
8235    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8236         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8237 
8238    Logically Collective on Mat and MatNullSpace
8239 
8240    Input Parameters:
8241 +  mat - the matrix
8242 -  nullsp - the null space object
8243 
8244    Level: advanced
8245 
8246    Notes:
8247       Overwrites any previous near null space that may have been attached
8248 
8249       You can remove the null space by calling this routine with an nullsp of NULL
8250 
8251    Concepts: null space^attaching to matrix
8252 
8253 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8254 @*/
8255 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8256 {
8257   PetscErrorCode ierr;
8258 
8259   PetscFunctionBegin;
8260   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8261   PetscValidType(mat,1);
8262   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8263   MatCheckPreallocated(mat,1);
8264   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8265   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8266   mat->nearnullsp = nullsp;
8267   PetscFunctionReturn(0);
8268 }
8269 
8270 /*@
8271    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8272 
8273    Not Collective
8274 
8275    Input Parameters:
8276 .  mat - the matrix
8277 
8278    Output Parameters:
8279 .  nullsp - the null space object, NULL if not set
8280 
8281    Level: developer
8282 
8283    Concepts: null space^attaching to matrix
8284 
8285 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8286 @*/
8287 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8288 {
8289   PetscFunctionBegin;
8290   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8291   PetscValidType(mat,1);
8292   PetscValidPointer(nullsp,2);
8293   MatCheckPreallocated(mat,1);
8294   *nullsp = mat->nearnullsp;
8295   PetscFunctionReturn(0);
8296 }
8297 
8298 /*@C
8299    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8300 
8301    Collective on Mat
8302 
8303    Input Parameters:
8304 +  mat - the matrix
8305 .  row - row/column permutation
8306 .  fill - expected fill factor >= 1.0
8307 -  level - level of fill, for ICC(k)
8308 
8309    Notes:
8310    Probably really in-place only when level of fill is zero, otherwise allocates
8311    new space to store factored matrix and deletes previous memory.
8312 
8313    Most users should employ the simplified KSP interface for linear solvers
8314    instead of working directly with matrix algebra routines such as this.
8315    See, e.g., KSPCreate().
8316 
8317    Level: developer
8318 
8319    Concepts: matrices^incomplete Cholesky factorization
8320    Concepts: Cholesky factorization
8321 
8322 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8323 
8324     Developer Note: fortran interface is not autogenerated as the f90
8325     interface defintion cannot be generated correctly [due to MatFactorInfo]
8326 
8327 @*/
8328 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8329 {
8330   PetscErrorCode ierr;
8331 
8332   PetscFunctionBegin;
8333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8334   PetscValidType(mat,1);
8335   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8336   PetscValidPointer(info,3);
8337   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8338   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8339   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8340   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8341   MatCheckPreallocated(mat,1);
8342   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8343   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8344   PetscFunctionReturn(0);
8345 }
8346 
8347 /*@
8348    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8349          ghosted ones.
8350 
8351    Not Collective
8352 
8353    Input Parameters:
8354 +  mat - the matrix
8355 -  diag = the diagonal values, including ghost ones
8356 
8357    Level: developer
8358 
8359    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8360 
8361 .seealso: MatDiagonalScale()
8362 @*/
8363 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8364 {
8365   PetscErrorCode ierr;
8366   PetscMPIInt    size;
8367 
8368   PetscFunctionBegin;
8369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8370   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8371   PetscValidType(mat,1);
8372 
8373   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8374   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8375   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8376   if (size == 1) {
8377     PetscInt n,m;
8378     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8379     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8380     if (m == n) {
8381       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8382     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8383   } else {
8384     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8385   }
8386   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8387   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8388   PetscFunctionReturn(0);
8389 }
8390 
8391 /*@
8392    MatGetInertia - Gets the inertia from a factored matrix
8393 
8394    Collective on Mat
8395 
8396    Input Parameter:
8397 .  mat - the matrix
8398 
8399    Output Parameters:
8400 +   nneg - number of negative eigenvalues
8401 .   nzero - number of zero eigenvalues
8402 -   npos - number of positive eigenvalues
8403 
8404    Level: advanced
8405 
8406    Notes: Matrix must have been factored by MatCholeskyFactor()
8407 
8408 
8409 @*/
8410 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8411 {
8412   PetscErrorCode ierr;
8413 
8414   PetscFunctionBegin;
8415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8416   PetscValidType(mat,1);
8417   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8418   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8419   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8420   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8421   PetscFunctionReturn(0);
8422 }
8423 
8424 /* ----------------------------------------------------------------*/
8425 /*@C
8426    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8427 
8428    Neighbor-wise Collective on Mat and Vecs
8429 
8430    Input Parameters:
8431 +  mat - the factored matrix
8432 -  b - the right-hand-side vectors
8433 
8434    Output Parameter:
8435 .  x - the result vectors
8436 
8437    Notes:
8438    The vectors b and x cannot be the same.  I.e., one cannot
8439    call MatSolves(A,x,x).
8440 
8441    Notes:
8442    Most users should employ the simplified KSP interface for linear solvers
8443    instead of working directly with matrix algebra routines such as this.
8444    See, e.g., KSPCreate().
8445 
8446    Level: developer
8447 
8448    Concepts: matrices^triangular solves
8449 
8450 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8451 @*/
8452 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8453 {
8454   PetscErrorCode ierr;
8455 
8456   PetscFunctionBegin;
8457   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8458   PetscValidType(mat,1);
8459   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8460   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8461   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8462 
8463   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8464   MatCheckPreallocated(mat,1);
8465   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8466   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8467   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8468   PetscFunctionReturn(0);
8469 }
8470 
8471 /*@
8472    MatIsSymmetric - Test whether a matrix is symmetric
8473 
8474    Collective on Mat
8475 
8476    Input Parameter:
8477 +  A - the matrix to test
8478 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8479 
8480    Output Parameters:
8481 .  flg - the result
8482 
8483    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8484 
8485    Level: intermediate
8486 
8487    Concepts: matrix^symmetry
8488 
8489 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8490 @*/
8491 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8492 {
8493   PetscErrorCode ierr;
8494 
8495   PetscFunctionBegin;
8496   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8497   PetscValidPointer(flg,2);
8498 
8499   if (!A->symmetric_set) {
8500     if (!A->ops->issymmetric) {
8501       MatType mattype;
8502       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8503       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8504     }
8505     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8506     if (!tol) {
8507       A->symmetric_set = PETSC_TRUE;
8508       A->symmetric     = *flg;
8509       if (A->symmetric) {
8510         A->structurally_symmetric_set = PETSC_TRUE;
8511         A->structurally_symmetric     = PETSC_TRUE;
8512       }
8513     }
8514   } else if (A->symmetric) {
8515     *flg = PETSC_TRUE;
8516   } else if (!tol) {
8517     *flg = PETSC_FALSE;
8518   } else {
8519     if (!A->ops->issymmetric) {
8520       MatType mattype;
8521       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8522       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8523     }
8524     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8525   }
8526   PetscFunctionReturn(0);
8527 }
8528 
8529 /*@
8530    MatIsHermitian - Test whether a matrix is Hermitian
8531 
8532    Collective on Mat
8533 
8534    Input Parameter:
8535 +  A - the matrix to test
8536 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8537 
8538    Output Parameters:
8539 .  flg - the result
8540 
8541    Level: intermediate
8542 
8543    Concepts: matrix^symmetry
8544 
8545 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8546           MatIsSymmetricKnown(), MatIsSymmetric()
8547 @*/
8548 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8549 {
8550   PetscErrorCode ierr;
8551 
8552   PetscFunctionBegin;
8553   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8554   PetscValidPointer(flg,2);
8555 
8556   if (!A->hermitian_set) {
8557     if (!A->ops->ishermitian) {
8558       MatType mattype;
8559       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8560       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8561     }
8562     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8563     if (!tol) {
8564       A->hermitian_set = PETSC_TRUE;
8565       A->hermitian     = *flg;
8566       if (A->hermitian) {
8567         A->structurally_symmetric_set = PETSC_TRUE;
8568         A->structurally_symmetric     = PETSC_TRUE;
8569       }
8570     }
8571   } else if (A->hermitian) {
8572     *flg = PETSC_TRUE;
8573   } else if (!tol) {
8574     *flg = PETSC_FALSE;
8575   } else {
8576     if (!A->ops->ishermitian) {
8577       MatType mattype;
8578       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8579       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8580     }
8581     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8582   }
8583   PetscFunctionReturn(0);
8584 }
8585 
8586 /*@
8587    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8588 
8589    Not Collective
8590 
8591    Input Parameter:
8592 .  A - the matrix to check
8593 
8594    Output Parameters:
8595 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8596 -  flg - the result
8597 
8598    Level: advanced
8599 
8600    Concepts: matrix^symmetry
8601 
8602    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8603          if you want it explicitly checked
8604 
8605 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8606 @*/
8607 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8608 {
8609   PetscFunctionBegin;
8610   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8611   PetscValidPointer(set,2);
8612   PetscValidPointer(flg,3);
8613   if (A->symmetric_set) {
8614     *set = PETSC_TRUE;
8615     *flg = A->symmetric;
8616   } else {
8617     *set = PETSC_FALSE;
8618   }
8619   PetscFunctionReturn(0);
8620 }
8621 
8622 /*@
8623    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8624 
8625    Not Collective
8626 
8627    Input Parameter:
8628 .  A - the matrix to check
8629 
8630    Output Parameters:
8631 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8632 -  flg - the result
8633 
8634    Level: advanced
8635 
8636    Concepts: matrix^symmetry
8637 
8638    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8639          if you want it explicitly checked
8640 
8641 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8642 @*/
8643 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8644 {
8645   PetscFunctionBegin;
8646   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8647   PetscValidPointer(set,2);
8648   PetscValidPointer(flg,3);
8649   if (A->hermitian_set) {
8650     *set = PETSC_TRUE;
8651     *flg = A->hermitian;
8652   } else {
8653     *set = PETSC_FALSE;
8654   }
8655   PetscFunctionReturn(0);
8656 }
8657 
8658 /*@
8659    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8660 
8661    Collective on Mat
8662 
8663    Input Parameter:
8664 .  A - the matrix to test
8665 
8666    Output Parameters:
8667 .  flg - the result
8668 
8669    Level: intermediate
8670 
8671    Concepts: matrix^symmetry
8672 
8673 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8674 @*/
8675 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8676 {
8677   PetscErrorCode ierr;
8678 
8679   PetscFunctionBegin;
8680   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8681   PetscValidPointer(flg,2);
8682   if (!A->structurally_symmetric_set) {
8683     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8684     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8685 
8686     A->structurally_symmetric_set = PETSC_TRUE;
8687   }
8688   *flg = A->structurally_symmetric;
8689   PetscFunctionReturn(0);
8690 }
8691 
8692 /*@
8693    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8694        to be communicated to other processors during the MatAssemblyBegin/End() process
8695 
8696     Not collective
8697 
8698    Input Parameter:
8699 .   vec - the vector
8700 
8701    Output Parameters:
8702 +   nstash   - the size of the stash
8703 .   reallocs - the number of additional mallocs incurred.
8704 .   bnstash   - the size of the block stash
8705 -   breallocs - the number of additional mallocs incurred.in the block stash
8706 
8707    Level: advanced
8708 
8709 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8710 
8711 @*/
8712 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8713 {
8714   PetscErrorCode ierr;
8715 
8716   PetscFunctionBegin;
8717   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8718   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8719   PetscFunctionReturn(0);
8720 }
8721 
8722 /*@C
8723    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8724      parallel layout
8725 
8726    Collective on Mat
8727 
8728    Input Parameter:
8729 .  mat - the matrix
8730 
8731    Output Parameter:
8732 +   right - (optional) vector that the matrix can be multiplied against
8733 -   left - (optional) vector that the matrix vector product can be stored in
8734 
8735    Notes:
8736     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().
8737 
8738   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8739 
8740   Level: advanced
8741 
8742 .seealso: MatCreate(), VecDestroy()
8743 @*/
8744 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8745 {
8746   PetscErrorCode ierr;
8747 
8748   PetscFunctionBegin;
8749   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8750   PetscValidType(mat,1);
8751   if (mat->ops->getvecs) {
8752     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8753   } else {
8754     PetscInt rbs,cbs;
8755     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8756     if (right) {
8757       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8758       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8759       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8760       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8761       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8762       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8763     }
8764     if (left) {
8765       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8766       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8767       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8768       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8769       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8770       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8771     }
8772   }
8773   PetscFunctionReturn(0);
8774 }
8775 
8776 /*@C
8777    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8778      with default values.
8779 
8780    Not Collective
8781 
8782    Input Parameters:
8783 .    info - the MatFactorInfo data structure
8784 
8785 
8786    Notes: The solvers are generally used through the KSP and PC objects, for example
8787           PCLU, PCILU, PCCHOLESKY, PCICC
8788 
8789    Level: developer
8790 
8791 .seealso: MatFactorInfo
8792 
8793     Developer Note: fortran interface is not autogenerated as the f90
8794     interface defintion cannot be generated correctly [due to MatFactorInfo]
8795 
8796 @*/
8797 
8798 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8799 {
8800   PetscErrorCode ierr;
8801 
8802   PetscFunctionBegin;
8803   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8804   PetscFunctionReturn(0);
8805 }
8806 
8807 /*@
8808    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8809 
8810    Collective on Mat
8811 
8812    Input Parameters:
8813 +  mat - the factored matrix
8814 -  is - the index set defining the Schur indices (0-based)
8815 
8816    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8817 
8818    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8819 
8820    Level: developer
8821 
8822    Concepts:
8823 
8824 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8825           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8826 
8827 @*/
8828 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8829 {
8830   PetscErrorCode ierr,(*f)(Mat,IS);
8831 
8832   PetscFunctionBegin;
8833   PetscValidType(mat,1);
8834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8835   PetscValidType(is,2);
8836   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8837   PetscCheckSameComm(mat,1,is,2);
8838   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8839   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8840   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");
8841   if (mat->schur) {
8842     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8843   }
8844   ierr = (*f)(mat,is);CHKERRQ(ierr);
8845   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8846   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8847   PetscFunctionReturn(0);
8848 }
8849 
8850 /*@
8851   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8852 
8853    Logically Collective on Mat
8854 
8855    Input Parameters:
8856 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8857 .  S - location where to return the Schur complement, can be NULL
8858 -  status - the status of the Schur complement matrix, can be NULL
8859 
8860    Notes:
8861    You must call MatFactorSetSchurIS() before calling this routine.
8862 
8863    The routine provides a copy of the Schur matrix stored within the solver data structures.
8864    The caller must destroy the object when it is no longer needed.
8865    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8866 
8867    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)
8868 
8869    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
8870    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8871 
8872    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8873 
8874    Level: advanced
8875 
8876    References:
8877 
8878 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8879 @*/
8880 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8881 {
8882   PetscErrorCode ierr;
8883 
8884   PetscFunctionBegin;
8885   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8886   if (S) PetscValidPointer(S,2);
8887   if (status) PetscValidPointer(status,3);
8888   if (S) {
8889     PetscErrorCode (*f)(Mat,Mat*);
8890 
8891     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8892     if (f) {
8893       ierr = (*f)(F,S);CHKERRQ(ierr);
8894     } else {
8895       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8896     }
8897   }
8898   if (status) *status = F->schur_status;
8899   PetscFunctionReturn(0);
8900 }
8901 
8902 /*@
8903   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8904 
8905    Logically Collective on Mat
8906 
8907    Input Parameters:
8908 +  F - the factored matrix obtained by calling MatGetFactor()
8909 .  *S - location where to return the Schur complement, can be NULL
8910 -  status - the status of the Schur complement matrix, can be NULL
8911 
8912    Notes:
8913    You must call MatFactorSetSchurIS() before calling this routine.
8914 
8915    Schur complement mode is currently implemented for sequential matrices.
8916    The routine returns a the Schur Complement stored within the data strutures of the solver.
8917    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8918    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8919 
8920    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8921 
8922    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8923 
8924    Level: advanced
8925 
8926    References:
8927 
8928 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8929 @*/
8930 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8931 {
8932   PetscFunctionBegin;
8933   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8934   if (S) PetscValidPointer(S,2);
8935   if (status) PetscValidPointer(status,3);
8936   if (S) *S = F->schur;
8937   if (status) *status = F->schur_status;
8938   PetscFunctionReturn(0);
8939 }
8940 
8941 /*@
8942   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8943 
8944    Logically Collective on Mat
8945 
8946    Input Parameters:
8947 +  F - the factored matrix obtained by calling MatGetFactor()
8948 .  *S - location where the Schur complement is stored
8949 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8950 
8951    Notes:
8952 
8953    Level: advanced
8954 
8955    References:
8956 
8957 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8958 @*/
8959 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8960 {
8961   PetscErrorCode ierr;
8962 
8963   PetscFunctionBegin;
8964   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8965   if (S) {
8966     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8967     *S = NULL;
8968   }
8969   F->schur_status = status;
8970   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8971   PetscFunctionReturn(0);
8972 }
8973 
8974 /*@
8975   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8976 
8977    Logically Collective on Mat
8978 
8979    Input Parameters:
8980 +  F - the factored matrix obtained by calling MatGetFactor()
8981 .  rhs - location where the right hand side of the Schur complement system is stored
8982 -  sol - location where the solution of the Schur complement system has to be returned
8983 
8984    Notes:
8985    The sizes of the vectors should match the size of the Schur complement
8986 
8987    Must be called after MatFactorSetSchurIS()
8988 
8989    Level: advanced
8990 
8991    References:
8992 
8993 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8994 @*/
8995 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8996 {
8997   PetscErrorCode ierr;
8998 
8999   PetscFunctionBegin;
9000   PetscValidType(F,1);
9001   PetscValidType(rhs,2);
9002   PetscValidType(sol,3);
9003   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9004   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9005   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9006   PetscCheckSameComm(F,1,rhs,2);
9007   PetscCheckSameComm(F,1,sol,3);
9008   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9009   switch (F->schur_status) {
9010   case MAT_FACTOR_SCHUR_FACTORED:
9011     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9012     break;
9013   case MAT_FACTOR_SCHUR_INVERTED:
9014     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9015     break;
9016   default:
9017     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9018     break;
9019   }
9020   PetscFunctionReturn(0);
9021 }
9022 
9023 /*@
9024   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9025 
9026    Logically Collective on Mat
9027 
9028    Input Parameters:
9029 +  F - the factored matrix obtained by calling MatGetFactor()
9030 .  rhs - location where the right hand side of the Schur complement system is stored
9031 -  sol - location where the solution of the Schur complement system has to be returned
9032 
9033    Notes:
9034    The sizes of the vectors should match the size of the Schur complement
9035 
9036    Must be called after MatFactorSetSchurIS()
9037 
9038    Level: advanced
9039 
9040    References:
9041 
9042 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9043 @*/
9044 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9045 {
9046   PetscErrorCode ierr;
9047 
9048   PetscFunctionBegin;
9049   PetscValidType(F,1);
9050   PetscValidType(rhs,2);
9051   PetscValidType(sol,3);
9052   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9053   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9054   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9055   PetscCheckSameComm(F,1,rhs,2);
9056   PetscCheckSameComm(F,1,sol,3);
9057   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9058   switch (F->schur_status) {
9059   case MAT_FACTOR_SCHUR_FACTORED:
9060     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9061     break;
9062   case MAT_FACTOR_SCHUR_INVERTED:
9063     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9064     break;
9065   default:
9066     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9067     break;
9068   }
9069   PetscFunctionReturn(0);
9070 }
9071 
9072 /*@
9073   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9074 
9075    Logically Collective on Mat
9076 
9077    Input Parameters:
9078 +  F - the factored matrix obtained by calling MatGetFactor()
9079 
9080    Notes: Must be called after MatFactorSetSchurIS().
9081 
9082    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9083 
9084    Level: advanced
9085 
9086    References:
9087 
9088 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9089 @*/
9090 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9091 {
9092   PetscErrorCode ierr;
9093 
9094   PetscFunctionBegin;
9095   PetscValidType(F,1);
9096   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9097   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9098   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9099   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9100   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9101   PetscFunctionReturn(0);
9102 }
9103 
9104 /*@
9105   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9106 
9107    Logically Collective on Mat
9108 
9109    Input Parameters:
9110 +  F - the factored matrix obtained by calling MatGetFactor()
9111 
9112    Notes: Must be called after MatFactorSetSchurIS().
9113 
9114    Level: advanced
9115 
9116    References:
9117 
9118 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9119 @*/
9120 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9121 {
9122   PetscErrorCode ierr;
9123 
9124   PetscFunctionBegin;
9125   PetscValidType(F,1);
9126   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9127   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9128   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9129   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9130   PetscFunctionReturn(0);
9131 }
9132 
9133 /*@
9134    MatPtAP - Creates the matrix product C = P^T * A * P
9135 
9136    Neighbor-wise Collective on Mat
9137 
9138    Input Parameters:
9139 +  A - the matrix
9140 .  P - the projection matrix
9141 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9142 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9143           if the result is a dense matrix this is irrelevent
9144 
9145    Output Parameters:
9146 .  C - the product matrix
9147 
9148    Notes:
9149    C will be created and must be destroyed by the user with MatDestroy().
9150 
9151    This routine is currently only implemented for pairs of AIJ matrices and classes
9152    which inherit from AIJ.
9153 
9154    Level: intermediate
9155 
9156 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9157 @*/
9158 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9159 {
9160   PetscErrorCode ierr;
9161   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9162   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9163   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9164   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9165 
9166   PetscFunctionBegin;
9167   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
9168   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
9169 
9170   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9171   PetscValidType(A,1);
9172   MatCheckPreallocated(A,1);
9173   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9174   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9175   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9176   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9177   PetscValidType(P,2);
9178   MatCheckPreallocated(P,2);
9179   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9180   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9181 
9182   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);
9183   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);
9184   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9185   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9186 
9187   if (scall == MAT_REUSE_MATRIX) {
9188     PetscValidPointer(*C,5);
9189     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9190     if (viatranspose || viamatmatmatmult) {
9191       Mat Pt;
9192       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9193       if (viamatmatmatmult) {
9194         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9195       } else {
9196         Mat AP;
9197         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9198         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9199         ierr = MatDestroy(&AP);CHKERRQ(ierr);
9200       }
9201       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9202     } else {
9203       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9204       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9205       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9206       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9207       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9208     }
9209     PetscFunctionReturn(0);
9210   }
9211 
9212   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9213   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9214 
9215   fA = A->ops->ptap;
9216   fP = P->ops->ptap;
9217   if (fP == fA) {
9218     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9219     ptap = fA;
9220   } else {
9221     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9222     char ptapname[256];
9223     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9224     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9225     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9226     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9227     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9228     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9229     if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
9230   }
9231 
9232   if (viatranspose || viamatmatmatmult) {
9233     Mat Pt;
9234     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9235     if (viamatmatmatmult) {
9236       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9237       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
9238     } else {
9239       Mat AP;
9240       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9241       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9242       ierr = MatDestroy(&AP);CHKERRQ(ierr);
9243       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
9244     }
9245     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9246   } else {
9247     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9248     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9249     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9250   }
9251   PetscFunctionReturn(0);
9252 }
9253 
9254 /*@
9255    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9256 
9257    Neighbor-wise Collective on Mat
9258 
9259    Input Parameters:
9260 +  A - the matrix
9261 -  P - the projection matrix
9262 
9263    Output Parameters:
9264 .  C - the product matrix
9265 
9266    Notes:
9267    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9268    the user using MatDeatroy().
9269 
9270    This routine is currently only implemented for pairs of AIJ matrices and classes
9271    which inherit from AIJ.  C will be of type MATAIJ.
9272 
9273    Level: intermediate
9274 
9275 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9276 @*/
9277 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9278 {
9279   PetscErrorCode ierr;
9280 
9281   PetscFunctionBegin;
9282   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9283   PetscValidType(A,1);
9284   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9285   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9286   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9287   PetscValidType(P,2);
9288   MatCheckPreallocated(P,2);
9289   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9290   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9291   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9292   PetscValidType(C,3);
9293   MatCheckPreallocated(C,3);
9294   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9295   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);
9296   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);
9297   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);
9298   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);
9299   MatCheckPreallocated(A,1);
9300 
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   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9351   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9352   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9353 
9354   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9355   PetscFunctionReturn(0);
9356 }
9357 
9358 /*@
9359    MatRARt - Creates the matrix product C = R * A * R^T
9360 
9361    Neighbor-wise Collective on Mat
9362 
9363    Input Parameters:
9364 +  A - the matrix
9365 .  R - the projection matrix
9366 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9367 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9368           if the result is a dense matrix this is irrelevent
9369 
9370    Output Parameters:
9371 .  C - the product matrix
9372 
9373    Notes:
9374    C will be created and must be destroyed by the user with MatDestroy().
9375 
9376    This routine is currently only implemented for pairs of AIJ matrices and classes
9377    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9378    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9379    We recommend using MatPtAP().
9380 
9381    Level: intermediate
9382 
9383 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9384 @*/
9385 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9386 {
9387   PetscErrorCode ierr;
9388 
9389   PetscFunctionBegin;
9390   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9391   PetscValidType(A,1);
9392   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9393   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9394   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9395   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9396   PetscValidType(R,2);
9397   MatCheckPreallocated(R,2);
9398   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9399   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9400   PetscValidPointer(C,3);
9401   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);
9402 
9403   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9404   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9405   MatCheckPreallocated(A,1);
9406 
9407   if (!A->ops->rart) {
9408     Mat Rt;
9409     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9410     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9411     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9412   }
9413   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9414   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9415   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9416   PetscFunctionReturn(0);
9417 }
9418 
9419 /*@
9420    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9421 
9422    Neighbor-wise Collective on Mat
9423 
9424    Input Parameters:
9425 +  A - the matrix
9426 -  R - the projection matrix
9427 
9428    Output Parameters:
9429 .  C - the product matrix
9430 
9431    Notes:
9432    C must have been created by calling MatRARtSymbolic and must be destroyed by
9433    the user using MatDestroy().
9434 
9435    This routine is currently only implemented for pairs of AIJ matrices and classes
9436    which inherit from AIJ.  C will be of type MATAIJ.
9437 
9438    Level: intermediate
9439 
9440 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9441 @*/
9442 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9443 {
9444   PetscErrorCode ierr;
9445 
9446   PetscFunctionBegin;
9447   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9448   PetscValidType(A,1);
9449   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9450   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9451   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9452   PetscValidType(R,2);
9453   MatCheckPreallocated(R,2);
9454   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9455   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9456   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9457   PetscValidType(C,3);
9458   MatCheckPreallocated(C,3);
9459   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9460   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);
9461   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);
9462   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);
9463   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);
9464   MatCheckPreallocated(A,1);
9465 
9466   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9467   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9468   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9469   PetscFunctionReturn(0);
9470 }
9471 
9472 /*@
9473    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9474 
9475    Neighbor-wise Collective on Mat
9476 
9477    Input Parameters:
9478 +  A - the matrix
9479 -  R - the projection matrix
9480 
9481    Output Parameters:
9482 .  C - the (i,j) structure of the product matrix
9483 
9484    Notes:
9485    C will be created and must be destroyed by the user with MatDestroy().
9486 
9487    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9488    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9489    this (i,j) structure by calling MatRARtNumeric().
9490 
9491    Level: intermediate
9492 
9493 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9494 @*/
9495 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9496 {
9497   PetscErrorCode ierr;
9498 
9499   PetscFunctionBegin;
9500   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9501   PetscValidType(A,1);
9502   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9503   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9504   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9505   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9506   PetscValidType(R,2);
9507   MatCheckPreallocated(R,2);
9508   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9509   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9510   PetscValidPointer(C,3);
9511 
9512   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);
9513   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);
9514   MatCheckPreallocated(A,1);
9515   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9516   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9517   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9518 
9519   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9520   PetscFunctionReturn(0);
9521 }
9522 
9523 /*@
9524    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9525 
9526    Neighbor-wise Collective on Mat
9527 
9528    Input Parameters:
9529 +  A - the left matrix
9530 .  B - the right matrix
9531 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9532 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9533           if the result is a dense matrix this is irrelevent
9534 
9535    Output Parameters:
9536 .  C - the product matrix
9537 
9538    Notes:
9539    Unless scall is MAT_REUSE_MATRIX C will be created.
9540 
9541    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
9542    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9543 
9544    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9545    actually needed.
9546 
9547    If you have many matrices with the same non-zero structure to multiply, you
9548    should either
9549 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9550 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9551    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
9552    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9553 
9554    Level: intermediate
9555 
9556 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9557 @*/
9558 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9559 {
9560   PetscErrorCode ierr;
9561   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9562   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9563   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9564 
9565   PetscFunctionBegin;
9566   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9567   PetscValidType(A,1);
9568   MatCheckPreallocated(A,1);
9569   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9570   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9571   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9572   PetscValidType(B,2);
9573   MatCheckPreallocated(B,2);
9574   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9575   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9576   PetscValidPointer(C,3);
9577   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9578   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);
9579   if (scall == MAT_REUSE_MATRIX) {
9580     PetscValidPointer(*C,5);
9581     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9582     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9583     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9584     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9585     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9586     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9587     PetscFunctionReturn(0);
9588   }
9589   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9590   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9591 
9592   fA = A->ops->matmult;
9593   fB = B->ops->matmult;
9594   if (fB == fA) {
9595     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9596     mult = fB;
9597   } else {
9598     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9599     char multname[256];
9600     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9601     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9602     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9603     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9604     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9605     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9606     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);
9607   }
9608   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9609   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9610   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9611   PetscFunctionReturn(0);
9612 }
9613 
9614 /*@
9615    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9616    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9617 
9618    Neighbor-wise Collective on Mat
9619 
9620    Input Parameters:
9621 +  A - the left matrix
9622 .  B - the right matrix
9623 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9624       if C is a dense matrix this is irrelevent
9625 
9626    Output Parameters:
9627 .  C - the product matrix
9628 
9629    Notes:
9630    Unless scall is MAT_REUSE_MATRIX C will be created.
9631 
9632    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9633    actually needed.
9634 
9635    This routine is currently implemented for
9636     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9637     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9638     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9639 
9640    Level: intermediate
9641 
9642    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9643      We should incorporate them into PETSc.
9644 
9645 .seealso: MatMatMult(), MatMatMultNumeric()
9646 @*/
9647 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9648 {
9649   PetscErrorCode ierr;
9650   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9651   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9652   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9653 
9654   PetscFunctionBegin;
9655   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9656   PetscValidType(A,1);
9657   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9658   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9659 
9660   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9661   PetscValidType(B,2);
9662   MatCheckPreallocated(B,2);
9663   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9664   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9665   PetscValidPointer(C,3);
9666 
9667   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);
9668   if (fill == PETSC_DEFAULT) fill = 2.0;
9669   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9670   MatCheckPreallocated(A,1);
9671 
9672   Asymbolic = A->ops->matmultsymbolic;
9673   Bsymbolic = B->ops->matmultsymbolic;
9674   if (Asymbolic == Bsymbolic) {
9675     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9676     symbolic = Bsymbolic;
9677   } else { /* dispatch based on the type of A and B */
9678     char symbolicname[256];
9679     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9680     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9681     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9682     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9683     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9684     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9685     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);
9686   }
9687   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9688   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9689   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9690   PetscFunctionReturn(0);
9691 }
9692 
9693 /*@
9694    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9695    Call this routine after first calling MatMatMultSymbolic().
9696 
9697    Neighbor-wise Collective on Mat
9698 
9699    Input Parameters:
9700 +  A - the left matrix
9701 -  B - the right matrix
9702 
9703    Output Parameters:
9704 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9705 
9706    Notes:
9707    C must have been created with MatMatMultSymbolic().
9708 
9709    This routine is currently implemented for
9710     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9711     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9712     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9713 
9714    Level: intermediate
9715 
9716 .seealso: MatMatMult(), MatMatMultSymbolic()
9717 @*/
9718 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9719 {
9720   PetscErrorCode ierr;
9721 
9722   PetscFunctionBegin;
9723   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9724   PetscFunctionReturn(0);
9725 }
9726 
9727 /*@
9728    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9729 
9730    Neighbor-wise Collective on Mat
9731 
9732    Input Parameters:
9733 +  A - the left matrix
9734 .  B - the right matrix
9735 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9736 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9737 
9738    Output Parameters:
9739 .  C - the product matrix
9740 
9741    Notes:
9742    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9743 
9744    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9745 
9746   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9747    actually needed.
9748 
9749    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9750 
9751    Level: intermediate
9752 
9753 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9754 @*/
9755 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9756 {
9757   PetscErrorCode ierr;
9758   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9759   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9760 
9761   PetscFunctionBegin;
9762   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9763   PetscValidType(A,1);
9764   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9765   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9766   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9767   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9768   PetscValidType(B,2);
9769   MatCheckPreallocated(B,2);
9770   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9771   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9772   PetscValidPointer(C,3);
9773   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);
9774   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9775   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9776   MatCheckPreallocated(A,1);
9777 
9778   fA = A->ops->mattransposemult;
9779   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9780   fB = B->ops->mattransposemult;
9781   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9782   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);
9783 
9784   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9785   if (scall == MAT_INITIAL_MATRIX) {
9786     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9787     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9788     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9789   }
9790   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9791   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9792   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9793   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9794   PetscFunctionReturn(0);
9795 }
9796 
9797 /*@
9798    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9799 
9800    Neighbor-wise Collective on Mat
9801 
9802    Input Parameters:
9803 +  A - the left matrix
9804 .  B - the right matrix
9805 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9806 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9807 
9808    Output Parameters:
9809 .  C - the product matrix
9810 
9811    Notes:
9812    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9813 
9814    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9815 
9816   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9817    actually needed.
9818 
9819    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9820    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9821 
9822    Level: intermediate
9823 
9824 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9825 @*/
9826 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9827 {
9828   PetscErrorCode ierr;
9829   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9830   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9831   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9832 
9833   PetscFunctionBegin;
9834   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9835   PetscValidType(A,1);
9836   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9837   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9838   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9839   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9840   PetscValidType(B,2);
9841   MatCheckPreallocated(B,2);
9842   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9843   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9844   PetscValidPointer(C,3);
9845   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);
9846   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9847   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9848   MatCheckPreallocated(A,1);
9849 
9850   fA = A->ops->transposematmult;
9851   fB = B->ops->transposematmult;
9852   if (fB==fA) {
9853     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9854     transposematmult = fA;
9855   } else {
9856     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9857     char multname[256];
9858     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9859     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9860     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9861     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9862     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9863     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9864     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);
9865   }
9866   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9867   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9868   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9869   PetscFunctionReturn(0);
9870 }
9871 
9872 /*@
9873    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9874 
9875    Neighbor-wise Collective on Mat
9876 
9877    Input Parameters:
9878 +  A - the left matrix
9879 .  B - the middle matrix
9880 .  C - the right matrix
9881 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9882 -  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
9883           if the result is a dense matrix this is irrelevent
9884 
9885    Output Parameters:
9886 .  D - the product matrix
9887 
9888    Notes:
9889    Unless scall is MAT_REUSE_MATRIX D will be created.
9890 
9891    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9892 
9893    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9894    actually needed.
9895 
9896    If you have many matrices with the same non-zero structure to multiply, you
9897    should use MAT_REUSE_MATRIX in all calls but the first or
9898 
9899    Level: intermediate
9900 
9901 .seealso: MatMatMult, MatPtAP()
9902 @*/
9903 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9904 {
9905   PetscErrorCode ierr;
9906   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9907   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9908   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9909   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9910 
9911   PetscFunctionBegin;
9912   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9913   PetscValidType(A,1);
9914   MatCheckPreallocated(A,1);
9915   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9916   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9917   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9918   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9919   PetscValidType(B,2);
9920   MatCheckPreallocated(B,2);
9921   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9922   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9923   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9924   PetscValidPointer(C,3);
9925   MatCheckPreallocated(C,3);
9926   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9927   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9928   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);
9929   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);
9930   if (scall == MAT_REUSE_MATRIX) {
9931     PetscValidPointer(*D,6);
9932     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9933     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9934     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9935     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9936     PetscFunctionReturn(0);
9937   }
9938   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9939   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9940 
9941   fA = A->ops->matmatmult;
9942   fB = B->ops->matmatmult;
9943   fC = C->ops->matmatmult;
9944   if (fA == fB && fA == fC) {
9945     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9946     mult = fA;
9947   } else {
9948     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9949     char multname[256];
9950     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9951     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9952     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9953     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9954     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9955     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9956     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9957     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9958     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);
9959   }
9960   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9961   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9962   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9963   PetscFunctionReturn(0);
9964 }
9965 
9966 /*@
9967    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9968 
9969    Collective on Mat
9970 
9971    Input Parameters:
9972 +  mat - the matrix
9973 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9974 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9975 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9976 
9977    Output Parameter:
9978 .  matredundant - redundant matrix
9979 
9980    Notes:
9981    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9982    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9983 
9984    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9985    calling it.
9986 
9987    Level: advanced
9988 
9989    Concepts: subcommunicator
9990    Concepts: duplicate matrix
9991 
9992 .seealso: MatDestroy()
9993 @*/
9994 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9995 {
9996   PetscErrorCode ierr;
9997   MPI_Comm       comm;
9998   PetscMPIInt    size;
9999   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10000   Mat_Redundant  *redund=NULL;
10001   PetscSubcomm   psubcomm=NULL;
10002   MPI_Comm       subcomm_in=subcomm;
10003   Mat            *matseq;
10004   IS             isrow,iscol;
10005   PetscBool      newsubcomm=PETSC_FALSE;
10006 
10007   PetscFunctionBegin;
10008   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10009   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10010     PetscValidPointer(*matredundant,5);
10011     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10012   }
10013 
10014   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10015   if (size == 1 || nsubcomm == 1) {
10016     if (reuse == MAT_INITIAL_MATRIX) {
10017       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10018     } else {
10019       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");
10020       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10021     }
10022     PetscFunctionReturn(0);
10023   }
10024 
10025   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10026   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10027   MatCheckPreallocated(mat,1);
10028 
10029   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10030   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10031     /* create psubcomm, then get subcomm */
10032     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10033     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10034     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10035 
10036     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10037     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10038     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10039     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10040     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10041     newsubcomm = PETSC_TRUE;
10042     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10043   }
10044 
10045   /* get isrow, iscol and a local sequential matrix matseq[0] */
10046   if (reuse == MAT_INITIAL_MATRIX) {
10047     mloc_sub = PETSC_DECIDE;
10048     nloc_sub = PETSC_DECIDE;
10049     if (bs < 1) {
10050       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10051       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10052     } else {
10053       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10054       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10055     }
10056     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10057     rstart = rend - mloc_sub;
10058     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10059     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10060   } else { /* reuse == MAT_REUSE_MATRIX */
10061     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");
10062     /* retrieve subcomm */
10063     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10064     redund = (*matredundant)->redundant;
10065     isrow  = redund->isrow;
10066     iscol  = redund->iscol;
10067     matseq = redund->matseq;
10068   }
10069   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10070 
10071   /* get matredundant over subcomm */
10072   if (reuse == MAT_INITIAL_MATRIX) {
10073     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10074 
10075     /* create a supporting struct and attach it to C for reuse */
10076     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10077     (*matredundant)->redundant = redund;
10078     redund->isrow              = isrow;
10079     redund->iscol              = iscol;
10080     redund->matseq             = matseq;
10081     if (newsubcomm) {
10082       redund->subcomm          = subcomm;
10083     } else {
10084       redund->subcomm          = MPI_COMM_NULL;
10085     }
10086   } else {
10087     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10088   }
10089   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10090   PetscFunctionReturn(0);
10091 }
10092 
10093 /*@C
10094    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10095    a given 'mat' object. Each submatrix can span multiple procs.
10096 
10097    Collective on Mat
10098 
10099    Input Parameters:
10100 +  mat - the matrix
10101 .  subcomm - the subcommunicator obtained by com_split(comm)
10102 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10103 
10104    Output Parameter:
10105 .  subMat - 'parallel submatrices each spans a given subcomm
10106 
10107   Notes:
10108   The submatrix partition across processors is dictated by 'subComm' a
10109   communicator obtained by com_split(comm). The comm_split
10110   is not restriced to be grouped with consecutive original ranks.
10111 
10112   Due the comm_split() usage, the parallel layout of the submatrices
10113   map directly to the layout of the original matrix [wrt the local
10114   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10115   into the 'DiagonalMat' of the subMat, hence it is used directly from
10116   the subMat. However the offDiagMat looses some columns - and this is
10117   reconstructed with MatSetValues()
10118 
10119   Level: advanced
10120 
10121   Concepts: subcommunicator
10122   Concepts: submatrices
10123 
10124 .seealso: MatCreateSubMatrices()
10125 @*/
10126 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10127 {
10128   PetscErrorCode ierr;
10129   PetscMPIInt    commsize,subCommSize;
10130 
10131   PetscFunctionBegin;
10132   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10133   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10134   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10135 
10136   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");
10137   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10138   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10139   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10140   PetscFunctionReturn(0);
10141 }
10142 
10143 /*@
10144    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10145 
10146    Not Collective
10147 
10148    Input Arguments:
10149    mat - matrix to extract local submatrix from
10150    isrow - local row indices for submatrix
10151    iscol - local column indices for submatrix
10152 
10153    Output Arguments:
10154    submat - the submatrix
10155 
10156    Level: intermediate
10157 
10158    Notes:
10159    The submat should be returned with MatRestoreLocalSubMatrix().
10160 
10161    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10162    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10163 
10164    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10165    MatSetValuesBlockedLocal() will also be implemented.
10166 
10167    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10168    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10169 
10170 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10171 @*/
10172 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10173 {
10174   PetscErrorCode ierr;
10175 
10176   PetscFunctionBegin;
10177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10178   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10179   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10180   PetscCheckSameComm(isrow,2,iscol,3);
10181   PetscValidPointer(submat,4);
10182   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10183 
10184   if (mat->ops->getlocalsubmatrix) {
10185     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10186   } else {
10187     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10188   }
10189   PetscFunctionReturn(0);
10190 }
10191 
10192 /*@
10193    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10194 
10195    Not Collective
10196 
10197    Input Arguments:
10198    mat - matrix to extract local submatrix from
10199    isrow - local row indices for submatrix
10200    iscol - local column indices for submatrix
10201    submat - the submatrix
10202 
10203    Level: intermediate
10204 
10205 .seealso: MatGetLocalSubMatrix()
10206 @*/
10207 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10208 {
10209   PetscErrorCode ierr;
10210 
10211   PetscFunctionBegin;
10212   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10213   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10214   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10215   PetscCheckSameComm(isrow,2,iscol,3);
10216   PetscValidPointer(submat,4);
10217   if (*submat) {
10218     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10219   }
10220 
10221   if (mat->ops->restorelocalsubmatrix) {
10222     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10223   } else {
10224     ierr = MatDestroy(submat);CHKERRQ(ierr);
10225   }
10226   *submat = NULL;
10227   PetscFunctionReturn(0);
10228 }
10229 
10230 /* --------------------------------------------------------*/
10231 /*@
10232    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10233 
10234    Collective on Mat
10235 
10236    Input Parameter:
10237 .  mat - the matrix
10238 
10239    Output Parameter:
10240 .  is - if any rows have zero diagonals this contains the list of them
10241 
10242    Level: developer
10243 
10244    Concepts: matrix-vector product
10245 
10246 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10247 @*/
10248 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10249 {
10250   PetscErrorCode ierr;
10251 
10252   PetscFunctionBegin;
10253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10254   PetscValidType(mat,1);
10255   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10256   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10257 
10258   if (!mat->ops->findzerodiagonals) {
10259     Vec                diag;
10260     const PetscScalar *a;
10261     PetscInt          *rows;
10262     PetscInt           rStart, rEnd, r, nrow = 0;
10263 
10264     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10265     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10266     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10267     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10268     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10269     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10270     nrow = 0;
10271     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10272     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10273     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10274     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10275   } else {
10276     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10277   }
10278   PetscFunctionReturn(0);
10279 }
10280 
10281 /*@
10282    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10283 
10284    Collective on Mat
10285 
10286    Input Parameter:
10287 .  mat - the matrix
10288 
10289    Output Parameter:
10290 .  is - contains the list of rows with off block diagonal entries
10291 
10292    Level: developer
10293 
10294    Concepts: matrix-vector product
10295 
10296 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10297 @*/
10298 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10299 {
10300   PetscErrorCode ierr;
10301 
10302   PetscFunctionBegin;
10303   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10304   PetscValidType(mat,1);
10305   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10306   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10307 
10308   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10309   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10310   PetscFunctionReturn(0);
10311 }
10312 
10313 /*@C
10314   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10315 
10316   Collective on Mat
10317 
10318   Input Parameters:
10319 . mat - the matrix
10320 
10321   Output Parameters:
10322 . values - the block inverses in column major order (FORTRAN-like)
10323 
10324    Note:
10325    This routine is not available from Fortran.
10326 
10327   Level: advanced
10328 @*/
10329 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10330 {
10331   PetscErrorCode ierr;
10332 
10333   PetscFunctionBegin;
10334   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10335   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10336   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10337   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10338   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10339   PetscFunctionReturn(0);
10340 }
10341 
10342 /*@C
10343     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10344     via MatTransposeColoringCreate().
10345 
10346     Collective on MatTransposeColoring
10347 
10348     Input Parameter:
10349 .   c - coloring context
10350 
10351     Level: intermediate
10352 
10353 .seealso: MatTransposeColoringCreate()
10354 @*/
10355 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10356 {
10357   PetscErrorCode       ierr;
10358   MatTransposeColoring matcolor=*c;
10359 
10360   PetscFunctionBegin;
10361   if (!matcolor) PetscFunctionReturn(0);
10362   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10363 
10364   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10365   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10366   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10367   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10368   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10369   if (matcolor->brows>0) {
10370     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10371   }
10372   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10373   PetscFunctionReturn(0);
10374 }
10375 
10376 /*@C
10377     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10378     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10379     MatTransposeColoring to sparse B.
10380 
10381     Collective on MatTransposeColoring
10382 
10383     Input Parameters:
10384 +   B - sparse matrix B
10385 .   Btdense - symbolic dense matrix B^T
10386 -   coloring - coloring context created with MatTransposeColoringCreate()
10387 
10388     Output Parameter:
10389 .   Btdense - dense matrix B^T
10390 
10391     Level: advanced
10392 
10393      Notes: These are used internally for some implementations of MatRARt()
10394 
10395 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10396 
10397 .keywords: coloring
10398 @*/
10399 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10400 {
10401   PetscErrorCode ierr;
10402 
10403   PetscFunctionBegin;
10404   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10405   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10406   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10407 
10408   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10409   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10410   PetscFunctionReturn(0);
10411 }
10412 
10413 /*@C
10414     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10415     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10416     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10417     Csp from Cden.
10418 
10419     Collective on MatTransposeColoring
10420 
10421     Input Parameters:
10422 +   coloring - coloring context created with MatTransposeColoringCreate()
10423 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10424 
10425     Output Parameter:
10426 .   Csp - sparse matrix
10427 
10428     Level: advanced
10429 
10430      Notes: These are used internally for some implementations of MatRARt()
10431 
10432 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10433 
10434 .keywords: coloring
10435 @*/
10436 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10437 {
10438   PetscErrorCode ierr;
10439 
10440   PetscFunctionBegin;
10441   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10442   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10443   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10444 
10445   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10446   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10447   PetscFunctionReturn(0);
10448 }
10449 
10450 /*@C
10451    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10452 
10453    Collective on Mat
10454 
10455    Input Parameters:
10456 +  mat - the matrix product C
10457 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10458 
10459     Output Parameter:
10460 .   color - the new coloring context
10461 
10462     Level: intermediate
10463 
10464 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10465            MatTransColoringApplyDenToSp()
10466 @*/
10467 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10468 {
10469   MatTransposeColoring c;
10470   MPI_Comm             comm;
10471   PetscErrorCode       ierr;
10472 
10473   PetscFunctionBegin;
10474   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10475   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10476   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10477 
10478   c->ctype = iscoloring->ctype;
10479   if (mat->ops->transposecoloringcreate) {
10480     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10481   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10482 
10483   *color = c;
10484   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10485   PetscFunctionReturn(0);
10486 }
10487 
10488 /*@
10489       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10490         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10491         same, otherwise it will be larger
10492 
10493      Not Collective
10494 
10495   Input Parameter:
10496 .    A  - the matrix
10497 
10498   Output Parameter:
10499 .    state - the current state
10500 
10501   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10502          different matrices
10503 
10504   Level: intermediate
10505 
10506 @*/
10507 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10508 {
10509   PetscFunctionBegin;
10510   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10511   *state = mat->nonzerostate;
10512   PetscFunctionReturn(0);
10513 }
10514 
10515 /*@
10516       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10517                  matrices from each processor
10518 
10519     Collective on MPI_Comm
10520 
10521    Input Parameters:
10522 +    comm - the communicators the parallel matrix will live on
10523 .    seqmat - the input sequential matrices
10524 .    n - number of local columns (or PETSC_DECIDE)
10525 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10526 
10527    Output Parameter:
10528 .    mpimat - the parallel matrix generated
10529 
10530     Level: advanced
10531 
10532    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10533 
10534 @*/
10535 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10536 {
10537   PetscErrorCode ierr;
10538 
10539   PetscFunctionBegin;
10540   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10541   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");
10542 
10543   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10544   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10545   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10546   PetscFunctionReturn(0);
10547 }
10548 
10549 /*@
10550      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10551                  ranks' ownership ranges.
10552 
10553     Collective on A
10554 
10555    Input Parameters:
10556 +    A   - the matrix to create subdomains from
10557 -    N   - requested number of subdomains
10558 
10559 
10560    Output Parameters:
10561 +    n   - number of subdomains resulting on this rank
10562 -    iss - IS list with indices of subdomains on this rank
10563 
10564     Level: advanced
10565 
10566     Notes: number of subdomains must be smaller than the communicator size
10567 @*/
10568 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10569 {
10570   MPI_Comm        comm,subcomm;
10571   PetscMPIInt     size,rank,color;
10572   PetscInt        rstart,rend,k;
10573   PetscErrorCode  ierr;
10574 
10575   PetscFunctionBegin;
10576   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10577   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10578   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10579   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);
10580   *n = 1;
10581   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10582   color = rank/k;
10583   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10584   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10585   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10586   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10587   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10588   PetscFunctionReturn(0);
10589 }
10590 
10591 /*@
10592    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10593 
10594    If the interpolation and restriction operators are the same, uses MatPtAP.
10595    If they are not the same, use MatMatMatMult.
10596 
10597    Once the coarse grid problem is constructed, correct for interpolation operators
10598    that are not of full rank, which can legitimately happen in the case of non-nested
10599    geometric multigrid.
10600 
10601    Input Parameters:
10602 +  restrct - restriction operator
10603 .  dA - fine grid matrix
10604 .  interpolate - interpolation operator
10605 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10606 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10607 
10608    Output Parameters:
10609 .  A - the Galerkin coarse matrix
10610 
10611    Options Database Key:
10612 .  -pc_mg_galerkin <both,pmat,mat,none>
10613 
10614    Level: developer
10615 
10616 .keywords: MG, multigrid, Galerkin
10617 
10618 .seealso: MatPtAP(), MatMatMatMult()
10619 @*/
10620 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10621 {
10622   PetscErrorCode ierr;
10623   IS             zerorows;
10624   Vec            diag;
10625 
10626   PetscFunctionBegin;
10627   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10628   /* Construct the coarse grid matrix */
10629   if (interpolate == restrct) {
10630     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10631   } else {
10632     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10633   }
10634 
10635   /* If the interpolation matrix is not of full rank, A will have zero rows.
10636      This can legitimately happen in the case of non-nested geometric multigrid.
10637      In that event, we set the rows of the matrix to the rows of the identity,
10638      ignoring the equations (as the RHS will also be zero). */
10639 
10640   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10641 
10642   if (zerorows != NULL) { /* if there are any zero rows */
10643     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10644     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10645     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10646     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10647     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10648     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10649   }
10650   PetscFunctionReturn(0);
10651 }
10652