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