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