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