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