xref: /petsc/src/mat/interface/matrix.c (revision 7a4b434895de22095ee510ddebd0ac79c1811f4e)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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_VECCUDA)
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   if (!next) {
4247     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4248     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4249     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4250     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4251     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4252     PetscFunctionReturn(0);
4253   }
4254   while (next) {
4255     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4256     if (flg) {
4257       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4258       inext = next->handlers;
4259       while (inext) {
4260         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4261         if (flg) {
4262           inext->getfactor[(int)ftype-1] = getfactor;
4263           PetscFunctionReturn(0);
4264         }
4265         iprev = inext;
4266         inext = inext->next;
4267       }
4268       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4269       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4270       iprev->next->getfactor[(int)ftype-1] = getfactor;
4271       PetscFunctionReturn(0);
4272     }
4273     prev = next;
4274     next = next->next;
4275   }
4276   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4277   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4278   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4279   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4280   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4281   PetscFunctionReturn(0);
4282 }
4283 
4284 /*@C
4285    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4286 
4287    Input Parameters:
4288 +    package - name of the package, for example petsc or superlu
4289 .    ftype - the type of factorization supported by the package
4290 -    mtype - the matrix type that works with this package
4291 
4292    Output Parameters:
4293 +   foundpackage - PETSC_TRUE if the package was registered
4294 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4295 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4296 
4297     Level: intermediate
4298 
4299 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4300 @*/
4301 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4302 {
4303   PetscErrorCode                 ierr;
4304   MatSolverTypeHolder         next = MatSolverTypeHolders;
4305   PetscBool                      flg;
4306   MatSolverTypeForSpecifcType inext;
4307 
4308   PetscFunctionBegin;
4309   if (foundpackage) *foundpackage = PETSC_FALSE;
4310   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4311   if (getfactor)    *getfactor    = NULL;
4312 
4313   if (package) {
4314     while (next) {
4315       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4316       if (flg) {
4317         if (foundpackage) *foundpackage = PETSC_TRUE;
4318         inext = next->handlers;
4319         while (inext) {
4320           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4321           if (flg) {
4322             if (foundmtype) *foundmtype = PETSC_TRUE;
4323             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4324             PetscFunctionReturn(0);
4325           }
4326           inext = inext->next;
4327         }
4328       }
4329       next = next->next;
4330     }
4331   } else {
4332     while (next) {
4333       inext = next->handlers;
4334       while (inext) {
4335         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4336         if (flg && inext->getfactor[(int)ftype-1]) {
4337           if (foundpackage) *foundpackage = PETSC_TRUE;
4338           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4339           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4340           PetscFunctionReturn(0);
4341         }
4342         inext = inext->next;
4343       }
4344       next = next->next;
4345     }
4346   }
4347   PetscFunctionReturn(0);
4348 }
4349 
4350 PetscErrorCode MatSolverTypeDestroy(void)
4351 {
4352   PetscErrorCode              ierr;
4353   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4354   MatSolverTypeForSpecifcType inext,iprev;
4355 
4356   PetscFunctionBegin;
4357   while (next) {
4358     ierr = PetscFree(next->name);CHKERRQ(ierr);
4359     inext = next->handlers;
4360     while (inext) {
4361       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4362       iprev = inext;
4363       inext = inext->next;
4364       ierr = PetscFree(iprev);CHKERRQ(ierr);
4365     }
4366     prev = next;
4367     next = next->next;
4368     ierr = PetscFree(prev);CHKERRQ(ierr);
4369   }
4370   MatSolverTypeHolders = NULL;
4371   PetscFunctionReturn(0);
4372 }
4373 
4374 /*@C
4375    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4376 
4377    Collective on Mat
4378 
4379    Input Parameters:
4380 +  mat - the matrix
4381 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4382 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4383 
4384    Output Parameters:
4385 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4386 
4387    Notes:
4388       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4389      such as pastix, superlu, mumps etc.
4390 
4391       PETSc must have been ./configure to use the external solver, using the option --download-package
4392 
4393    Level: intermediate
4394 
4395 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4396 @*/
4397 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4398 {
4399   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4400   PetscBool      foundpackage,foundmtype;
4401 
4402   PetscFunctionBegin;
4403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4404   PetscValidType(mat,1);
4405 
4406   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4407   MatCheckPreallocated(mat,1);
4408 
4409   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4410   if (!foundpackage) {
4411     if (type) {
4412       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4413     } else {
4414       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4415     }
4416   }
4417 
4418   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4419   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);
4420 
4421 #if defined(PETSC_USE_COMPLEX)
4422   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");
4423 #endif
4424 
4425   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4426   PetscFunctionReturn(0);
4427 }
4428 
4429 /*@C
4430    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4431 
4432    Not Collective
4433 
4434    Input Parameters:
4435 +  mat - the matrix
4436 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4437 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4438 
4439    Output Parameter:
4440 .    flg - PETSC_TRUE if the factorization is available
4441 
4442    Notes:
4443       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4444      such as pastix, superlu, mumps etc.
4445 
4446       PETSc must have been ./configure to use the external solver, using the option --download-package
4447 
4448    Level: intermediate
4449 
4450 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4451 @*/
4452 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4453 {
4454   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4455 
4456   PetscFunctionBegin;
4457   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4458   PetscValidType(mat,1);
4459 
4460   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4461   MatCheckPreallocated(mat,1);
4462 
4463   *flg = PETSC_FALSE;
4464   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4465   if (gconv) {
4466     *flg = PETSC_TRUE;
4467   }
4468   PetscFunctionReturn(0);
4469 }
4470 
4471 #include <petscdmtypes.h>
4472 
4473 /*@
4474    MatDuplicate - Duplicates a matrix including the non-zero structure.
4475 
4476    Collective on Mat
4477 
4478    Input Parameters:
4479 +  mat - the matrix
4480 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4481         See the manual page for MatDuplicateOption for an explanation of these options.
4482 
4483    Output Parameter:
4484 .  M - pointer to place new matrix
4485 
4486    Level: intermediate
4487 
4488    Concepts: matrices^duplicating
4489 
4490    Notes:
4491     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4492 
4493 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4494 @*/
4495 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4496 {
4497   PetscErrorCode ierr;
4498   Mat            B;
4499   PetscInt       i;
4500   DM             dm;
4501   void           (*viewf)(void);
4502 
4503   PetscFunctionBegin;
4504   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4505   PetscValidType(mat,1);
4506   PetscValidPointer(M,3);
4507   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4508   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4509   MatCheckPreallocated(mat,1);
4510 
4511   *M = 0;
4512   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4513   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4514   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4515   B    = *M;
4516 
4517   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4518   if (viewf) {
4519     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4520   }
4521 
4522   B->stencil.dim = mat->stencil.dim;
4523   B->stencil.noc = mat->stencil.noc;
4524   for (i=0; i<=mat->stencil.dim; i++) {
4525     B->stencil.dims[i]   = mat->stencil.dims[i];
4526     B->stencil.starts[i] = mat->stencil.starts[i];
4527   }
4528 
4529   B->nooffproczerorows = mat->nooffproczerorows;
4530   B->nooffprocentries  = mat->nooffprocentries;
4531 
4532   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4533   if (dm) {
4534     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4535   }
4536   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4537   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4538   PetscFunctionReturn(0);
4539 }
4540 
4541 /*@
4542    MatGetDiagonal - Gets the diagonal of a matrix.
4543 
4544    Logically Collective on Mat and Vec
4545 
4546    Input Parameters:
4547 +  mat - the matrix
4548 -  v - the vector for storing the diagonal
4549 
4550    Output Parameter:
4551 .  v - the diagonal of the matrix
4552 
4553    Level: intermediate
4554 
4555    Note:
4556    Currently only correct in parallel for square matrices.
4557 
4558    Concepts: matrices^accessing diagonals
4559 
4560 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4561 @*/
4562 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4563 {
4564   PetscErrorCode ierr;
4565 
4566   PetscFunctionBegin;
4567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4568   PetscValidType(mat,1);
4569   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4570   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4571   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4572   MatCheckPreallocated(mat,1);
4573 
4574   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4575   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4576   PetscFunctionReturn(0);
4577 }
4578 
4579 /*@C
4580    MatGetRowMin - Gets the minimum value (of the real part) of each
4581         row of the matrix
4582 
4583    Logically Collective on Mat and Vec
4584 
4585    Input Parameters:
4586 .  mat - the matrix
4587 
4588    Output Parameter:
4589 +  v - the vector for storing the maximums
4590 -  idx - the indices of the column found for each row (optional)
4591 
4592    Level: intermediate
4593 
4594    Notes:
4595     The result of this call are the same as if one converted the matrix to dense format
4596       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4597 
4598     This code is only implemented for a couple of matrix formats.
4599 
4600    Concepts: matrices^getting row maximums
4601 
4602 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4603           MatGetRowMax()
4604 @*/
4605 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4606 {
4607   PetscErrorCode ierr;
4608 
4609   PetscFunctionBegin;
4610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4611   PetscValidType(mat,1);
4612   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4613   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4614   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4615   MatCheckPreallocated(mat,1);
4616 
4617   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4618   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4619   PetscFunctionReturn(0);
4620 }
4621 
4622 /*@C
4623    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4624         row of the matrix
4625 
4626    Logically Collective on Mat and Vec
4627 
4628    Input Parameters:
4629 .  mat - the matrix
4630 
4631    Output Parameter:
4632 +  v - the vector for storing the minimums
4633 -  idx - the indices of the column found for each row (or NULL if not needed)
4634 
4635    Level: intermediate
4636 
4637    Notes:
4638     if a row is completely empty or has only 0.0 values then the idx[] value for that
4639     row is 0 (the first column).
4640 
4641     This code is only implemented for a couple of matrix formats.
4642 
4643    Concepts: matrices^getting row maximums
4644 
4645 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4646 @*/
4647 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4648 {
4649   PetscErrorCode ierr;
4650 
4651   PetscFunctionBegin;
4652   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4653   PetscValidType(mat,1);
4654   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4655   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4656   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4657   MatCheckPreallocated(mat,1);
4658   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4659 
4660   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4661   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4662   PetscFunctionReturn(0);
4663 }
4664 
4665 /*@C
4666    MatGetRowMax - Gets the maximum value (of the real part) of each
4667         row of the matrix
4668 
4669    Logically Collective on Mat and Vec
4670 
4671    Input Parameters:
4672 .  mat - the matrix
4673 
4674    Output Parameter:
4675 +  v - the vector for storing the maximums
4676 -  idx - the indices of the column found for each row (optional)
4677 
4678    Level: intermediate
4679 
4680    Notes:
4681     The result of this call are the same as if one converted the matrix to dense format
4682       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4683 
4684     This code is only implemented for a couple of matrix formats.
4685 
4686    Concepts: matrices^getting row maximums
4687 
4688 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4689 @*/
4690 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4691 {
4692   PetscErrorCode ierr;
4693 
4694   PetscFunctionBegin;
4695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4696   PetscValidType(mat,1);
4697   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4698   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4699   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4700   MatCheckPreallocated(mat,1);
4701 
4702   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4703   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4704   PetscFunctionReturn(0);
4705 }
4706 
4707 /*@C
4708    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4709         row of the matrix
4710 
4711    Logically Collective on Mat and Vec
4712 
4713    Input Parameters:
4714 .  mat - the matrix
4715 
4716    Output Parameter:
4717 +  v - the vector for storing the maximums
4718 -  idx - the indices of the column found for each row (or NULL if not needed)
4719 
4720    Level: intermediate
4721 
4722    Notes:
4723     if a row is completely empty or has only 0.0 values then the idx[] value for that
4724     row is 0 (the first column).
4725 
4726     This code is only implemented for a couple of matrix formats.
4727 
4728    Concepts: matrices^getting row maximums
4729 
4730 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4731 @*/
4732 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4733 {
4734   PetscErrorCode ierr;
4735 
4736   PetscFunctionBegin;
4737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4738   PetscValidType(mat,1);
4739   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4740   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4741   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4742   MatCheckPreallocated(mat,1);
4743   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4744 
4745   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4746   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4747   PetscFunctionReturn(0);
4748 }
4749 
4750 /*@
4751    MatGetRowSum - Gets the sum of each row of the matrix
4752 
4753    Logically or Neighborhood Collective on Mat and Vec
4754 
4755    Input Parameters:
4756 .  mat - the matrix
4757 
4758    Output Parameter:
4759 .  v - the vector for storing the sum of rows
4760 
4761    Level: intermediate
4762 
4763    Notes:
4764     This code is slow since it is not currently specialized for different formats
4765 
4766    Concepts: matrices^getting row sums
4767 
4768 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4769 @*/
4770 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4771 {
4772   Vec            ones;
4773   PetscErrorCode ierr;
4774 
4775   PetscFunctionBegin;
4776   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4777   PetscValidType(mat,1);
4778   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4779   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4780   MatCheckPreallocated(mat,1);
4781   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4782   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4783   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4784   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4785   PetscFunctionReturn(0);
4786 }
4787 
4788 /*@
4789    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4790 
4791    Collective on Mat
4792 
4793    Input Parameter:
4794 +  mat - the matrix to transpose
4795 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4796 
4797    Output Parameters:
4798 .  B - the transpose
4799 
4800    Notes:
4801      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4802 
4803      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4804 
4805      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4806 
4807    Level: intermediate
4808 
4809    Concepts: matrices^transposing
4810 
4811 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4812 @*/
4813 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4814 {
4815   PetscErrorCode ierr;
4816 
4817   PetscFunctionBegin;
4818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4819   PetscValidType(mat,1);
4820   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4821   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4822   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4823   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4824   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4825   MatCheckPreallocated(mat,1);
4826 
4827   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4828   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4829   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4830   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4831   PetscFunctionReturn(0);
4832 }
4833 
4834 /*@
4835    MatIsTranspose - Test whether a matrix is another one's transpose,
4836         or its own, in which case it tests symmetry.
4837 
4838    Collective on Mat
4839 
4840    Input Parameter:
4841 +  A - the matrix to test
4842 -  B - the matrix to test against, this can equal the first parameter
4843 
4844    Output Parameters:
4845 .  flg - the result
4846 
4847    Notes:
4848    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4849    has a running time of the order of the number of nonzeros; the parallel
4850    test involves parallel copies of the block-offdiagonal parts of the matrix.
4851 
4852    Level: intermediate
4853 
4854    Concepts: matrices^transposing, matrix^symmetry
4855 
4856 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4857 @*/
4858 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4859 {
4860   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4861 
4862   PetscFunctionBegin;
4863   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4864   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4865   PetscValidPointer(flg,3);
4866   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4867   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4868   *flg = PETSC_FALSE;
4869   if (f && g) {
4870     if (f == g) {
4871       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4872     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4873   } else {
4874     MatType mattype;
4875     if (!f) {
4876       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4877     } else {
4878       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4879     }
4880     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4881   }
4882   PetscFunctionReturn(0);
4883 }
4884 
4885 /*@
4886    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4887 
4888    Collective on Mat
4889 
4890    Input Parameter:
4891 +  mat - the matrix to transpose and complex conjugate
4892 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4893 
4894    Output Parameters:
4895 .  B - the Hermitian
4896 
4897    Level: intermediate
4898 
4899    Concepts: matrices^transposing, complex conjugatex
4900 
4901 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4902 @*/
4903 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4904 {
4905   PetscErrorCode ierr;
4906 
4907   PetscFunctionBegin;
4908   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4909 #if defined(PETSC_USE_COMPLEX)
4910   ierr = MatConjugate(*B);CHKERRQ(ierr);
4911 #endif
4912   PetscFunctionReturn(0);
4913 }
4914 
4915 /*@
4916    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4917 
4918    Collective on Mat
4919 
4920    Input Parameter:
4921 +  A - the matrix to test
4922 -  B - the matrix to test against, this can equal the first parameter
4923 
4924    Output Parameters:
4925 .  flg - the result
4926 
4927    Notes:
4928    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4929    has a running time of the order of the number of nonzeros; the parallel
4930    test involves parallel copies of the block-offdiagonal parts of the matrix.
4931 
4932    Level: intermediate
4933 
4934    Concepts: matrices^transposing, matrix^symmetry
4935 
4936 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4937 @*/
4938 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4939 {
4940   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4941 
4942   PetscFunctionBegin;
4943   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4944   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4945   PetscValidPointer(flg,3);
4946   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4947   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4948   if (f && g) {
4949     if (f==g) {
4950       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4951     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4952   }
4953   PetscFunctionReturn(0);
4954 }
4955 
4956 /*@
4957    MatPermute - Creates a new matrix with rows and columns permuted from the
4958    original.
4959 
4960    Collective on Mat
4961 
4962    Input Parameters:
4963 +  mat - the matrix to permute
4964 .  row - row permutation, each processor supplies only the permutation for its rows
4965 -  col - column permutation, each processor supplies only the permutation for its columns
4966 
4967    Output Parameters:
4968 .  B - the permuted matrix
4969 
4970    Level: advanced
4971 
4972    Note:
4973    The index sets map from row/col of permuted matrix to row/col of original matrix.
4974    The index sets should be on the same communicator as Mat and have the same local sizes.
4975 
4976    Concepts: matrices^permuting
4977 
4978 .seealso: MatGetOrdering(), ISAllGather()
4979 
4980 @*/
4981 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4982 {
4983   PetscErrorCode ierr;
4984 
4985   PetscFunctionBegin;
4986   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4987   PetscValidType(mat,1);
4988   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4989   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4990   PetscValidPointer(B,4);
4991   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4992   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4993   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4994   MatCheckPreallocated(mat,1);
4995 
4996   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4997   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4998   PetscFunctionReturn(0);
4999 }
5000 
5001 /*@
5002    MatEqual - Compares two matrices.
5003 
5004    Collective on Mat
5005 
5006    Input Parameters:
5007 +  A - the first matrix
5008 -  B - the second matrix
5009 
5010    Output Parameter:
5011 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5012 
5013    Level: intermediate
5014 
5015    Concepts: matrices^equality between
5016 @*/
5017 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5018 {
5019   PetscErrorCode ierr;
5020 
5021   PetscFunctionBegin;
5022   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5023   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5024   PetscValidType(A,1);
5025   PetscValidType(B,2);
5026   PetscValidIntPointer(flg,3);
5027   PetscCheckSameComm(A,1,B,2);
5028   MatCheckPreallocated(B,2);
5029   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5030   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5031   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);
5032   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5033   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5034   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);
5035   MatCheckPreallocated(A,1);
5036 
5037   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5038   PetscFunctionReturn(0);
5039 }
5040 
5041 /*@
5042    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5043    matrices that are stored as vectors.  Either of the two scaling
5044    matrices can be NULL.
5045 
5046    Collective on Mat
5047 
5048    Input Parameters:
5049 +  mat - the matrix to be scaled
5050 .  l - the left scaling vector (or NULL)
5051 -  r - the right scaling vector (or NULL)
5052 
5053    Notes:
5054    MatDiagonalScale() computes A = LAR, where
5055    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5056    The L scales the rows of the matrix, the R scales the columns of the matrix.
5057 
5058    Level: intermediate
5059 
5060    Concepts: matrices^diagonal scaling
5061    Concepts: diagonal scaling of matrices
5062 
5063 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5064 @*/
5065 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5066 {
5067   PetscErrorCode ierr;
5068 
5069   PetscFunctionBegin;
5070   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5071   PetscValidType(mat,1);
5072   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5073   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5074   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5075   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5076   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5077   MatCheckPreallocated(mat,1);
5078 
5079   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5080   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5081   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5082   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5083 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5084   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5085     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5086   }
5087 #endif
5088   PetscFunctionReturn(0);
5089 }
5090 
5091 /*@
5092     MatScale - Scales all elements of a matrix by a given number.
5093 
5094     Logically Collective on Mat
5095 
5096     Input Parameters:
5097 +   mat - the matrix to be scaled
5098 -   a  - the scaling value
5099 
5100     Output Parameter:
5101 .   mat - the scaled matrix
5102 
5103     Level: intermediate
5104 
5105     Concepts: matrices^scaling all entries
5106 
5107 .seealso: MatDiagonalScale()
5108 @*/
5109 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5110 {
5111   PetscErrorCode ierr;
5112 
5113   PetscFunctionBegin;
5114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5115   PetscValidType(mat,1);
5116   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5117   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5118   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5119   PetscValidLogicalCollectiveScalar(mat,a,2);
5120   MatCheckPreallocated(mat,1);
5121 
5122   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5123   if (a != (PetscScalar)1.0) {
5124     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5125     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5126 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5127     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5128       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5129     }
5130 #endif
5131   }
5132   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5133   PetscFunctionReturn(0);
5134 }
5135 
5136 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm)
5137 {
5138   PetscErrorCode ierr;
5139 
5140   PetscFunctionBegin;
5141   if (type == NORM_1 || type == NORM_INFINITY) {
5142     Vec l,r;
5143 
5144     ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr);
5145     if (type == NORM_INFINITY) {
5146       ierr = VecSet(r,1.);CHKERRQ(ierr);
5147       ierr = MatMult(A,r,l);CHKERRQ(ierr);
5148       ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr);
5149     } else {
5150       ierr = VecSet(l,1.);CHKERRQ(ierr);
5151       ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr);
5152       ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr);
5153     }
5154     ierr = VecDestroy(&l);CHKERRQ(ierr);
5155     ierr = VecDestroy(&r);CHKERRQ(ierr);
5156   } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type);
5157   PetscFunctionReturn(0);
5158 }
5159 
5160 /*@
5161    MatNorm - Calculates various norms of a matrix.
5162 
5163    Collective on Mat
5164 
5165    Input Parameters:
5166 +  mat - the matrix
5167 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5168 
5169    Output Parameters:
5170 .  nrm - the resulting norm
5171 
5172    Level: intermediate
5173 
5174    Concepts: matrices^norm
5175    Concepts: norm^of matrix
5176 @*/
5177 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5178 {
5179   PetscErrorCode ierr;
5180 
5181   PetscFunctionBegin;
5182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5183   PetscValidType(mat,1);
5184   PetscValidLogicalCollectiveEnum(mat,type,2);
5185   PetscValidScalarPointer(nrm,3);
5186 
5187   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5188   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5189   MatCheckPreallocated(mat,1);
5190 
5191   if (!mat->ops->norm) {
5192     ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr);
5193   } else {
5194     ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5195   }
5196   PetscFunctionReturn(0);
5197 }
5198 
5199 /*
5200      This variable is used to prevent counting of MatAssemblyBegin() that
5201    are called from within a MatAssemblyEnd().
5202 */
5203 static PetscInt MatAssemblyEnd_InUse = 0;
5204 /*@
5205    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5206    be called after completing all calls to MatSetValues().
5207 
5208    Collective on Mat
5209 
5210    Input Parameters:
5211 +  mat - the matrix
5212 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5213 
5214    Notes:
5215    MatSetValues() generally caches the values.  The matrix is ready to
5216    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5217    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5218    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5219    using the matrix.
5220 
5221    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5222    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
5223    a global collective operation requring all processes that share the matrix.
5224 
5225    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5226    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5227    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5228 
5229    Level: beginner
5230 
5231    Concepts: matrices^assembling
5232 
5233 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5234 @*/
5235 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5236 {
5237   PetscErrorCode ierr;
5238 
5239   PetscFunctionBegin;
5240   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5241   PetscValidType(mat,1);
5242   MatCheckPreallocated(mat,1);
5243   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5244   if (mat->assembled) {
5245     mat->was_assembled = PETSC_TRUE;
5246     mat->assembled     = PETSC_FALSE;
5247   }
5248   if (!MatAssemblyEnd_InUse) {
5249     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5250     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5251     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5252   } else if (mat->ops->assemblybegin) {
5253     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5254   }
5255   PetscFunctionReturn(0);
5256 }
5257 
5258 /*@
5259    MatAssembled - Indicates if a matrix has been assembled and is ready for
5260      use; for example, in matrix-vector product.
5261 
5262    Not Collective
5263 
5264    Input Parameter:
5265 .  mat - the matrix
5266 
5267    Output Parameter:
5268 .  assembled - PETSC_TRUE or PETSC_FALSE
5269 
5270    Level: advanced
5271 
5272    Concepts: matrices^assembled?
5273 
5274 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5275 @*/
5276 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5277 {
5278   PetscFunctionBegin;
5279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5280   PetscValidType(mat,1);
5281   PetscValidPointer(assembled,2);
5282   *assembled = mat->assembled;
5283   PetscFunctionReturn(0);
5284 }
5285 
5286 /*@
5287    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5288    be called after MatAssemblyBegin().
5289 
5290    Collective on Mat
5291 
5292    Input Parameters:
5293 +  mat - the matrix
5294 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5295 
5296    Options Database Keys:
5297 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5298 .  -mat_view ::ascii_info_detail - Prints more detailed info
5299 .  -mat_view - Prints matrix in ASCII format
5300 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5301 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5302 .  -display <name> - Sets display name (default is host)
5303 .  -draw_pause <sec> - Sets number of seconds to pause after display
5304 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5305 .  -viewer_socket_machine <machine> - Machine to use for socket
5306 .  -viewer_socket_port <port> - Port number to use for socket
5307 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5308 
5309    Notes:
5310    MatSetValues() generally caches the values.  The matrix is ready to
5311    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5312    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5313    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5314    using the matrix.
5315 
5316    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5317    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5318    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5319 
5320    Level: beginner
5321 
5322 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5323 @*/
5324 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5325 {
5326   PetscErrorCode  ierr;
5327   static PetscInt inassm = 0;
5328   PetscBool       flg    = PETSC_FALSE;
5329 
5330   PetscFunctionBegin;
5331   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5332   PetscValidType(mat,1);
5333 
5334   inassm++;
5335   MatAssemblyEnd_InUse++;
5336   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5337     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5338     if (mat->ops->assemblyend) {
5339       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5340     }
5341     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5342   } else if (mat->ops->assemblyend) {
5343     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5344   }
5345 
5346   /* Flush assembly is not a true assembly */
5347   if (type != MAT_FLUSH_ASSEMBLY) {
5348     mat->assembled = PETSC_TRUE; mat->num_ass++;
5349   }
5350   mat->insertmode = NOT_SET_VALUES;
5351   MatAssemblyEnd_InUse--;
5352   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5353   if (!mat->symmetric_eternal) {
5354     mat->symmetric_set              = PETSC_FALSE;
5355     mat->hermitian_set              = PETSC_FALSE;
5356     mat->structurally_symmetric_set = PETSC_FALSE;
5357   }
5358 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5359   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5360     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5361   }
5362 #endif
5363   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5364     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5365 
5366     if (mat->checksymmetryonassembly) {
5367       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5368       if (flg) {
5369         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5370       } else {
5371         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5372       }
5373     }
5374     if (mat->nullsp && mat->checknullspaceonassembly) {
5375       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5376     }
5377   }
5378   inassm--;
5379   PetscFunctionReturn(0);
5380 }
5381 
5382 /*@
5383    MatSetOption - Sets a parameter option for a matrix. Some options
5384    may be specific to certain storage formats.  Some options
5385    determine how values will be inserted (or added). Sorted,
5386    row-oriented input will generally assemble the fastest. The default
5387    is row-oriented.
5388 
5389    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5390 
5391    Input Parameters:
5392 +  mat - the matrix
5393 .  option - the option, one of those listed below (and possibly others),
5394 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5395 
5396   Options Describing Matrix Structure:
5397 +    MAT_SPD - symmetric positive definite
5398 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5399 .    MAT_HERMITIAN - transpose is the complex conjugation
5400 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5401 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5402                             you set to be kept with all future use of the matrix
5403                             including after MatAssemblyBegin/End() which could
5404                             potentially change the symmetry structure, i.e. you
5405                             KNOW the matrix will ALWAYS have the property you set.
5406 
5407 
5408    Options For Use with MatSetValues():
5409    Insert a logically dense subblock, which can be
5410 .    MAT_ROW_ORIENTED - row-oriented (default)
5411 
5412    Note these options reflect the data you pass in with MatSetValues(); it has
5413    nothing to do with how the data is stored internally in the matrix
5414    data structure.
5415 
5416    When (re)assembling a matrix, we can restrict the input for
5417    efficiency/debugging purposes.  These options include:
5418 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5419 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5420 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5421 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5422 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5423 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5424         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5425         performance for very large process counts.
5426 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5427         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5428         functions, instead sending only neighbor messages.
5429 
5430    Notes:
5431    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5432 
5433    Some options are relevant only for particular matrix types and
5434    are thus ignored by others.  Other options are not supported by
5435    certain matrix types and will generate an error message if set.
5436 
5437    If using a Fortran 77 module to compute a matrix, one may need to
5438    use the column-oriented option (or convert to the row-oriented
5439    format).
5440 
5441    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5442    that would generate a new entry in the nonzero structure is instead
5443    ignored.  Thus, if memory has not alredy been allocated for this particular
5444    data, then the insertion is ignored. For dense matrices, in which
5445    the entire array is allocated, no entries are ever ignored.
5446    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5447 
5448    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5449    that would generate a new entry in the nonzero structure instead produces
5450    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
5451 
5452    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5453    that would generate a new entry that has not been preallocated will
5454    instead produce an error. (Currently supported for AIJ and BAIJ formats
5455    only.) This is a useful flag when debugging matrix memory preallocation.
5456    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5457 
5458    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5459    other processors should be dropped, rather than stashed.
5460    This is useful if you know that the "owning" processor is also
5461    always generating the correct matrix entries, so that PETSc need
5462    not transfer duplicate entries generated on another processor.
5463 
5464    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5465    searches during matrix assembly. When this flag is set, the hash table
5466    is created during the first Matrix Assembly. This hash table is
5467    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5468    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5469    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5470    supported by MATMPIBAIJ format only.
5471 
5472    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5473    are kept in the nonzero structure
5474 
5475    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5476    a zero location in the matrix
5477 
5478    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5479 
5480    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5481         zero row routines and thus improves performance for very large process counts.
5482 
5483    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5484         part of the matrix (since they should match the upper triangular part).
5485 
5486    Notes:
5487     Can only be called after MatSetSizes() and MatSetType() have been set.
5488 
5489    Level: intermediate
5490 
5491    Concepts: matrices^setting options
5492 
5493 .seealso:  MatOption, Mat
5494 
5495 @*/
5496 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5497 {
5498   PetscErrorCode ierr;
5499 
5500   PetscFunctionBegin;
5501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5502   PetscValidType(mat,1);
5503   if (op > 0) {
5504     PetscValidLogicalCollectiveEnum(mat,op,2);
5505     PetscValidLogicalCollectiveBool(mat,flg,3);
5506   }
5507 
5508   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);
5509   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()");
5510 
5511   switch (op) {
5512   case MAT_NO_OFF_PROC_ENTRIES:
5513     mat->nooffprocentries = flg;
5514     PetscFunctionReturn(0);
5515     break;
5516   case MAT_SUBSET_OFF_PROC_ENTRIES:
5517     mat->subsetoffprocentries = flg;
5518     PetscFunctionReturn(0);
5519   case MAT_NO_OFF_PROC_ZERO_ROWS:
5520     mat->nooffproczerorows = flg;
5521     PetscFunctionReturn(0);
5522     break;
5523   case MAT_SPD:
5524     mat->spd_set = PETSC_TRUE;
5525     mat->spd     = flg;
5526     if (flg) {
5527       mat->symmetric                  = PETSC_TRUE;
5528       mat->structurally_symmetric     = PETSC_TRUE;
5529       mat->symmetric_set              = PETSC_TRUE;
5530       mat->structurally_symmetric_set = PETSC_TRUE;
5531     }
5532     break;
5533   case MAT_SYMMETRIC:
5534     mat->symmetric = flg;
5535     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5536     mat->symmetric_set              = PETSC_TRUE;
5537     mat->structurally_symmetric_set = flg;
5538 #if !defined(PETSC_USE_COMPLEX)
5539     mat->hermitian     = flg;
5540     mat->hermitian_set = PETSC_TRUE;
5541 #endif
5542     break;
5543   case MAT_HERMITIAN:
5544     mat->hermitian = flg;
5545     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5546     mat->hermitian_set              = PETSC_TRUE;
5547     mat->structurally_symmetric_set = flg;
5548 #if !defined(PETSC_USE_COMPLEX)
5549     mat->symmetric     = flg;
5550     mat->symmetric_set = PETSC_TRUE;
5551 #endif
5552     break;
5553   case MAT_STRUCTURALLY_SYMMETRIC:
5554     mat->structurally_symmetric     = flg;
5555     mat->structurally_symmetric_set = PETSC_TRUE;
5556     break;
5557   case MAT_SYMMETRY_ETERNAL:
5558     mat->symmetric_eternal = flg;
5559     break;
5560   case MAT_STRUCTURE_ONLY:
5561     mat->structure_only = flg;
5562     break;
5563   default:
5564     break;
5565   }
5566   if (mat->ops->setoption) {
5567     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5568   }
5569   PetscFunctionReturn(0);
5570 }
5571 
5572 /*@
5573    MatGetOption - Gets a parameter option that has been set for a matrix.
5574 
5575    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5576 
5577    Input Parameters:
5578 +  mat - the matrix
5579 -  option - the option, this only responds to certain options, check the code for which ones
5580 
5581    Output Parameter:
5582 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5583 
5584     Notes:
5585     Can only be called after MatSetSizes() and MatSetType() have been set.
5586 
5587    Level: intermediate
5588 
5589    Concepts: matrices^setting options
5590 
5591 .seealso:  MatOption, MatSetOption()
5592 
5593 @*/
5594 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5595 {
5596   PetscFunctionBegin;
5597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5598   PetscValidType(mat,1);
5599 
5600   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);
5601   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()");
5602 
5603   switch (op) {
5604   case MAT_NO_OFF_PROC_ENTRIES:
5605     *flg = mat->nooffprocentries;
5606     break;
5607   case MAT_NO_OFF_PROC_ZERO_ROWS:
5608     *flg = mat->nooffproczerorows;
5609     break;
5610   case MAT_SYMMETRIC:
5611     *flg = mat->symmetric;
5612     break;
5613   case MAT_HERMITIAN:
5614     *flg = mat->hermitian;
5615     break;
5616   case MAT_STRUCTURALLY_SYMMETRIC:
5617     *flg = mat->structurally_symmetric;
5618     break;
5619   case MAT_SYMMETRY_ETERNAL:
5620     *flg = mat->symmetric_eternal;
5621     break;
5622   case MAT_SPD:
5623     *flg = mat->spd;
5624     break;
5625   default:
5626     break;
5627   }
5628   PetscFunctionReturn(0);
5629 }
5630 
5631 /*@
5632    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5633    this routine retains the old nonzero structure.
5634 
5635    Logically Collective on Mat
5636 
5637    Input Parameters:
5638 .  mat - the matrix
5639 
5640    Level: intermediate
5641 
5642    Notes:
5643     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.
5644    See the Performance chapter of the users manual for information on preallocating matrices.
5645 
5646    Concepts: matrices^zeroing
5647 
5648 .seealso: MatZeroRows()
5649 @*/
5650 PetscErrorCode MatZeroEntries(Mat mat)
5651 {
5652   PetscErrorCode ierr;
5653 
5654   PetscFunctionBegin;
5655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5656   PetscValidType(mat,1);
5657   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5658   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");
5659   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5660   MatCheckPreallocated(mat,1);
5661 
5662   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5663   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5664   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5665   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5666 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5667   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5668     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5669   }
5670 #endif
5671   PetscFunctionReturn(0);
5672 }
5673 
5674 /*@
5675    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5676    of a set of rows and columns of a matrix.
5677 
5678    Collective on Mat
5679 
5680    Input Parameters:
5681 +  mat - the matrix
5682 .  numRows - the number of rows to remove
5683 .  rows - the global row indices
5684 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5685 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5686 -  b - optional vector of right hand side, that will be adjusted by provided solution
5687 
5688    Notes:
5689    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5690 
5691    The user can set a value in the diagonal entry (or for the AIJ and
5692    row formats can optionally remove the main diagonal entry from the
5693    nonzero structure as well, by passing 0.0 as the final argument).
5694 
5695    For the parallel case, all processes that share the matrix (i.e.,
5696    those in the communicator used for matrix creation) MUST call this
5697    routine, regardless of whether any rows being zeroed are owned by
5698    them.
5699 
5700    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5701    list only rows local to itself).
5702 
5703    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5704 
5705    Level: intermediate
5706 
5707    Concepts: matrices^zeroing rows
5708 
5709 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5710           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5711 @*/
5712 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5713 {
5714   PetscErrorCode ierr;
5715 
5716   PetscFunctionBegin;
5717   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5718   PetscValidType(mat,1);
5719   if (numRows) PetscValidIntPointer(rows,3);
5720   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5721   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5722   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5723   MatCheckPreallocated(mat,1);
5724 
5725   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5726   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5727   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5728 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5729   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5730     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5731   }
5732 #endif
5733   PetscFunctionReturn(0);
5734 }
5735 
5736 /*@
5737    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5738    of a set of rows and columns of a matrix.
5739 
5740    Collective on Mat
5741 
5742    Input Parameters:
5743 +  mat - the matrix
5744 .  is - the rows to zero
5745 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5746 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5747 -  b - optional vector of right hand side, that will be adjusted by provided solution
5748 
5749    Notes:
5750    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5751 
5752    The user can set a value in the diagonal entry (or for the AIJ and
5753    row formats can optionally remove the main diagonal entry from the
5754    nonzero structure as well, by passing 0.0 as the final argument).
5755 
5756    For the parallel case, all processes that share the matrix (i.e.,
5757    those in the communicator used for matrix creation) MUST call this
5758    routine, regardless of whether any rows being zeroed are owned by
5759    them.
5760 
5761    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5762    list only rows local to itself).
5763 
5764    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5765 
5766    Level: intermediate
5767 
5768    Concepts: matrices^zeroing rows
5769 
5770 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5771           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5772 @*/
5773 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5774 {
5775   PetscErrorCode ierr;
5776   PetscInt       numRows;
5777   const PetscInt *rows;
5778 
5779   PetscFunctionBegin;
5780   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5781   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5782   PetscValidType(mat,1);
5783   PetscValidType(is,2);
5784   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5785   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5786   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5787   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5788   PetscFunctionReturn(0);
5789 }
5790 
5791 /*@
5792    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5793    of a set of rows of a matrix.
5794 
5795    Collective on Mat
5796 
5797    Input Parameters:
5798 +  mat - the matrix
5799 .  numRows - the number of rows to remove
5800 .  rows - the global row indices
5801 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5802 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5803 -  b - optional vector of right hand side, that will be adjusted by provided solution
5804 
5805    Notes:
5806    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5807    but does not release memory.  For the dense and block diagonal
5808    formats this does not alter the nonzero structure.
5809 
5810    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5811    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5812    merely zeroed.
5813 
5814    The user can set a value in the diagonal entry (or for the AIJ and
5815    row formats can optionally remove the main diagonal entry from the
5816    nonzero structure as well, by passing 0.0 as the final argument).
5817 
5818    For the parallel case, all processes that share the matrix (i.e.,
5819    those in the communicator used for matrix creation) MUST call this
5820    routine, regardless of whether any rows being zeroed are owned by
5821    them.
5822 
5823    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5824    list only rows local to itself).
5825 
5826    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5827    owns that are to be zeroed. This saves a global synchronization in the implementation.
5828 
5829    Level: intermediate
5830 
5831    Concepts: matrices^zeroing rows
5832 
5833 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5834           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5835 @*/
5836 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5837 {
5838   PetscErrorCode ierr;
5839 
5840   PetscFunctionBegin;
5841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5842   PetscValidType(mat,1);
5843   if (numRows) PetscValidIntPointer(rows,3);
5844   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5845   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5846   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5847   MatCheckPreallocated(mat,1);
5848 
5849   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5850   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5851   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5852 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5853   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5854     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5855   }
5856 #endif
5857   PetscFunctionReturn(0);
5858 }
5859 
5860 /*@
5861    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5862    of a set of rows of a matrix.
5863 
5864    Collective on Mat
5865 
5866    Input Parameters:
5867 +  mat - the matrix
5868 .  is - index set of rows to remove
5869 .  diag - value put in all diagonals of eliminated rows
5870 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5871 -  b - optional vector of right hand side, that will be adjusted by provided solution
5872 
5873    Notes:
5874    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5875    but does not release memory.  For the dense and block diagonal
5876    formats this does not alter the nonzero structure.
5877 
5878    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5879    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5880    merely zeroed.
5881 
5882    The user can set a value in the diagonal entry (or for the AIJ and
5883    row formats can optionally remove the main diagonal entry from the
5884    nonzero structure as well, by passing 0.0 as the final argument).
5885 
5886    For the parallel case, all processes that share the matrix (i.e.,
5887    those in the communicator used for matrix creation) MUST call this
5888    routine, regardless of whether any rows being zeroed are owned by
5889    them.
5890 
5891    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5892    list only rows local to itself).
5893 
5894    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5895    owns that are to be zeroed. This saves a global synchronization in the implementation.
5896 
5897    Level: intermediate
5898 
5899    Concepts: matrices^zeroing rows
5900 
5901 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5902           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5903 @*/
5904 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5905 {
5906   PetscInt       numRows;
5907   const PetscInt *rows;
5908   PetscErrorCode ierr;
5909 
5910   PetscFunctionBegin;
5911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5912   PetscValidType(mat,1);
5913   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5914   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5915   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5916   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5917   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5918   PetscFunctionReturn(0);
5919 }
5920 
5921 /*@
5922    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5923    of a set of rows of a matrix. These rows must be local to the process.
5924 
5925    Collective on Mat
5926 
5927    Input Parameters:
5928 +  mat - the matrix
5929 .  numRows - the number of rows to remove
5930 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5931 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5932 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5933 -  b - optional vector of right hand side, that will be adjusted by provided solution
5934 
5935    Notes:
5936    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5937    but does not release memory.  For the dense and block diagonal
5938    formats this does not alter the nonzero structure.
5939 
5940    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5941    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5942    merely zeroed.
5943 
5944    The user can set a value in the diagonal entry (or for the AIJ and
5945    row formats can optionally remove the main diagonal entry from the
5946    nonzero structure as well, by passing 0.0 as the final argument).
5947 
5948    For the parallel case, all processes that share the matrix (i.e.,
5949    those in the communicator used for matrix creation) MUST call this
5950    routine, regardless of whether any rows being zeroed are owned by
5951    them.
5952 
5953    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5954    list only rows local to itself).
5955 
5956    The grid coordinates are across the entire grid, not just the local portion
5957 
5958    In Fortran idxm and idxn should be declared as
5959 $     MatStencil idxm(4,m)
5960    and the values inserted using
5961 $    idxm(MatStencil_i,1) = i
5962 $    idxm(MatStencil_j,1) = j
5963 $    idxm(MatStencil_k,1) = k
5964 $    idxm(MatStencil_c,1) = c
5965    etc
5966 
5967    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5968    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5969    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5970    DM_BOUNDARY_PERIODIC boundary type.
5971 
5972    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
5973    a single value per point) you can skip filling those indices.
5974 
5975    Level: intermediate
5976 
5977    Concepts: matrices^zeroing rows
5978 
5979 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5980           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5981 @*/
5982 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5983 {
5984   PetscInt       dim     = mat->stencil.dim;
5985   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5986   PetscInt       *dims   = mat->stencil.dims+1;
5987   PetscInt       *starts = mat->stencil.starts;
5988   PetscInt       *dxm    = (PetscInt*) rows;
5989   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5990   PetscErrorCode ierr;
5991 
5992   PetscFunctionBegin;
5993   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5994   PetscValidType(mat,1);
5995   if (numRows) PetscValidIntPointer(rows,3);
5996 
5997   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5998   for (i = 0; i < numRows; ++i) {
5999     /* Skip unused dimensions (they are ordered k, j, i, c) */
6000     for (j = 0; j < 3-sdim; ++j) dxm++;
6001     /* Local index in X dir */
6002     tmp = *dxm++ - starts[0];
6003     /* Loop over remaining dimensions */
6004     for (j = 0; j < dim-1; ++j) {
6005       /* If nonlocal, set index to be negative */
6006       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6007       /* Update local index */
6008       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6009     }
6010     /* Skip component slot if necessary */
6011     if (mat->stencil.noc) dxm++;
6012     /* Local row number */
6013     if (tmp >= 0) {
6014       jdxm[numNewRows++] = tmp;
6015     }
6016   }
6017   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6018   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6019   PetscFunctionReturn(0);
6020 }
6021 
6022 /*@
6023    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6024    of a set of rows and columns of a matrix.
6025 
6026    Collective on Mat
6027 
6028    Input Parameters:
6029 +  mat - the matrix
6030 .  numRows - the number of rows/columns to remove
6031 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6032 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6033 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6034 -  b - optional vector of right hand side, that will be adjusted by provided solution
6035 
6036    Notes:
6037    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6038    but does not release memory.  For the dense and block diagonal
6039    formats this does not alter the nonzero structure.
6040 
6041    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6042    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6043    merely zeroed.
6044 
6045    The user can set a value in the diagonal entry (or for the AIJ and
6046    row formats can optionally remove the main diagonal entry from the
6047    nonzero structure as well, by passing 0.0 as the final argument).
6048 
6049    For the parallel case, all processes that share the matrix (i.e.,
6050    those in the communicator used for matrix creation) MUST call this
6051    routine, regardless of whether any rows being zeroed are owned by
6052    them.
6053 
6054    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6055    list only rows local to itself, but the row/column numbers are given in local numbering).
6056 
6057    The grid coordinates are across the entire grid, not just the local portion
6058 
6059    In Fortran idxm and idxn should be declared as
6060 $     MatStencil idxm(4,m)
6061    and the values inserted using
6062 $    idxm(MatStencil_i,1) = i
6063 $    idxm(MatStencil_j,1) = j
6064 $    idxm(MatStencil_k,1) = k
6065 $    idxm(MatStencil_c,1) = c
6066    etc
6067 
6068    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6069    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6070    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6071    DM_BOUNDARY_PERIODIC boundary type.
6072 
6073    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
6074    a single value per point) you can skip filling those indices.
6075 
6076    Level: intermediate
6077 
6078    Concepts: matrices^zeroing rows
6079 
6080 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6081           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6082 @*/
6083 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6084 {
6085   PetscInt       dim     = mat->stencil.dim;
6086   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6087   PetscInt       *dims   = mat->stencil.dims+1;
6088   PetscInt       *starts = mat->stencil.starts;
6089   PetscInt       *dxm    = (PetscInt*) rows;
6090   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6091   PetscErrorCode ierr;
6092 
6093   PetscFunctionBegin;
6094   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6095   PetscValidType(mat,1);
6096   if (numRows) PetscValidIntPointer(rows,3);
6097 
6098   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6099   for (i = 0; i < numRows; ++i) {
6100     /* Skip unused dimensions (they are ordered k, j, i, c) */
6101     for (j = 0; j < 3-sdim; ++j) dxm++;
6102     /* Local index in X dir */
6103     tmp = *dxm++ - starts[0];
6104     /* Loop over remaining dimensions */
6105     for (j = 0; j < dim-1; ++j) {
6106       /* If nonlocal, set index to be negative */
6107       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6108       /* Update local index */
6109       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6110     }
6111     /* Skip component slot if necessary */
6112     if (mat->stencil.noc) dxm++;
6113     /* Local row number */
6114     if (tmp >= 0) {
6115       jdxm[numNewRows++] = tmp;
6116     }
6117   }
6118   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6119   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6120   PetscFunctionReturn(0);
6121 }
6122 
6123 /*@
6124    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6125    of a set of rows of a matrix; using local numbering of rows.
6126 
6127    Collective on Mat
6128 
6129    Input Parameters:
6130 +  mat - the matrix
6131 .  numRows - the number of rows to remove
6132 .  rows - the global row indices
6133 .  diag - value put in all diagonals of eliminated rows
6134 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6135 -  b - optional vector of right hand side, that will be adjusted by provided solution
6136 
6137    Notes:
6138    Before calling MatZeroRowsLocal(), the user must first set the
6139    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6140 
6141    For the AIJ matrix formats this removes the old nonzero structure,
6142    but does not release memory.  For the dense and block diagonal
6143    formats this does not alter the nonzero structure.
6144 
6145    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6146    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6147    merely zeroed.
6148 
6149    The user can set a value in the diagonal entry (or for the AIJ and
6150    row formats can optionally remove the main diagonal entry from the
6151    nonzero structure as well, by passing 0.0 as the final argument).
6152 
6153    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6154    owns that are to be zeroed. This saves a global synchronization in the implementation.
6155 
6156    Level: intermediate
6157 
6158    Concepts: matrices^zeroing
6159 
6160 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6161           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6162 @*/
6163 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6164 {
6165   PetscErrorCode ierr;
6166 
6167   PetscFunctionBegin;
6168   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6169   PetscValidType(mat,1);
6170   if (numRows) PetscValidIntPointer(rows,3);
6171   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6172   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6173   MatCheckPreallocated(mat,1);
6174 
6175   if (mat->ops->zerorowslocal) {
6176     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6177   } else {
6178     IS             is, newis;
6179     const PetscInt *newRows;
6180 
6181     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6182     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6183     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6184     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6185     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6186     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6187     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6188     ierr = ISDestroy(&is);CHKERRQ(ierr);
6189   }
6190   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6191 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6192   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6193     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6194   }
6195 #endif
6196   PetscFunctionReturn(0);
6197 }
6198 
6199 /*@
6200    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6201    of a set of rows of a matrix; using local numbering of rows.
6202 
6203    Collective on Mat
6204 
6205    Input Parameters:
6206 +  mat - the matrix
6207 .  is - index set of rows to remove
6208 .  diag - value put in all diagonals of eliminated rows
6209 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6210 -  b - optional vector of right hand side, that will be adjusted by provided solution
6211 
6212    Notes:
6213    Before calling MatZeroRowsLocalIS(), the user must first set the
6214    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6215 
6216    For the AIJ matrix formats this removes the old nonzero structure,
6217    but does not release memory.  For the dense and block diagonal
6218    formats this does not alter the nonzero structure.
6219 
6220    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6221    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6222    merely zeroed.
6223 
6224    The user can set a value in the diagonal entry (or for the AIJ and
6225    row formats can optionally remove the main diagonal entry from the
6226    nonzero structure as well, by passing 0.0 as the final argument).
6227 
6228    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6229    owns that are to be zeroed. This saves a global synchronization in the implementation.
6230 
6231    Level: intermediate
6232 
6233    Concepts: matrices^zeroing
6234 
6235 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6236           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6237 @*/
6238 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6239 {
6240   PetscErrorCode ierr;
6241   PetscInt       numRows;
6242   const PetscInt *rows;
6243 
6244   PetscFunctionBegin;
6245   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6246   PetscValidType(mat,1);
6247   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6248   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6249   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6250   MatCheckPreallocated(mat,1);
6251 
6252   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6253   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6254   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6255   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6256   PetscFunctionReturn(0);
6257 }
6258 
6259 /*@
6260    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6261    of a set of rows and columns of a matrix; using local numbering of rows.
6262 
6263    Collective on Mat
6264 
6265    Input Parameters:
6266 +  mat - the matrix
6267 .  numRows - the number of rows to remove
6268 .  rows - the global row indices
6269 .  diag - value put in all diagonals of eliminated rows
6270 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6271 -  b - optional vector of right hand side, that will be adjusted by provided solution
6272 
6273    Notes:
6274    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6275    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6276 
6277    The user can set a value in the diagonal entry (or for the AIJ and
6278    row formats can optionally remove the main diagonal entry from the
6279    nonzero structure as well, by passing 0.0 as the final argument).
6280 
6281    Level: intermediate
6282 
6283    Concepts: matrices^zeroing
6284 
6285 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6286           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6287 @*/
6288 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6289 {
6290   PetscErrorCode ierr;
6291   IS             is, newis;
6292   const PetscInt *newRows;
6293 
6294   PetscFunctionBegin;
6295   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6296   PetscValidType(mat,1);
6297   if (numRows) PetscValidIntPointer(rows,3);
6298   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6299   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6300   MatCheckPreallocated(mat,1);
6301 
6302   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6303   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6304   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6305   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6306   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6307   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6308   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6309   ierr = ISDestroy(&is);CHKERRQ(ierr);
6310   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6311 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6312   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6313     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6314   }
6315 #endif
6316   PetscFunctionReturn(0);
6317 }
6318 
6319 /*@
6320    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6321    of a set of rows and columns of a matrix; using local numbering of rows.
6322 
6323    Collective on Mat
6324 
6325    Input Parameters:
6326 +  mat - the matrix
6327 .  is - index set of rows to remove
6328 .  diag - value put in all diagonals of eliminated rows
6329 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6330 -  b - optional vector of right hand side, that will be adjusted by provided solution
6331 
6332    Notes:
6333    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6334    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6335 
6336    The user can set a value in the diagonal entry (or for the AIJ and
6337    row formats can optionally remove the main diagonal entry from the
6338    nonzero structure as well, by passing 0.0 as the final argument).
6339 
6340    Level: intermediate
6341 
6342    Concepts: matrices^zeroing
6343 
6344 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6345           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6346 @*/
6347 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6348 {
6349   PetscErrorCode ierr;
6350   PetscInt       numRows;
6351   const PetscInt *rows;
6352 
6353   PetscFunctionBegin;
6354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6355   PetscValidType(mat,1);
6356   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6357   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6358   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6359   MatCheckPreallocated(mat,1);
6360 
6361   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6362   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6363   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6364   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6365   PetscFunctionReturn(0);
6366 }
6367 
6368 /*@C
6369    MatGetSize - Returns the numbers of rows and columns in a matrix.
6370 
6371    Not Collective
6372 
6373    Input Parameter:
6374 .  mat - the matrix
6375 
6376    Output Parameters:
6377 +  m - the number of global rows
6378 -  n - the number of global columns
6379 
6380    Note: both output parameters can be NULL on input.
6381 
6382    Level: beginner
6383 
6384    Concepts: matrices^size
6385 
6386 .seealso: MatGetLocalSize()
6387 @*/
6388 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6389 {
6390   PetscFunctionBegin;
6391   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6392   if (m) *m = mat->rmap->N;
6393   if (n) *n = mat->cmap->N;
6394   PetscFunctionReturn(0);
6395 }
6396 
6397 /*@C
6398    MatGetLocalSize - Returns the number of rows and columns in a matrix
6399    stored locally.  This information may be implementation dependent, so
6400    use with care.
6401 
6402    Not Collective
6403 
6404    Input Parameters:
6405 .  mat - the matrix
6406 
6407    Output Parameters:
6408 +  m - the number of local rows
6409 -  n - the number of local columns
6410 
6411    Note: both output parameters can be NULL on input.
6412 
6413    Level: beginner
6414 
6415    Concepts: matrices^local size
6416 
6417 .seealso: MatGetSize()
6418 @*/
6419 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6420 {
6421   PetscFunctionBegin;
6422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6423   if (m) PetscValidIntPointer(m,2);
6424   if (n) PetscValidIntPointer(n,3);
6425   if (m) *m = mat->rmap->n;
6426   if (n) *n = mat->cmap->n;
6427   PetscFunctionReturn(0);
6428 }
6429 
6430 /*@C
6431    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6432    this processor. (The columns of the "diagonal block")
6433 
6434    Not Collective, unless matrix has not been allocated, then collective on Mat
6435 
6436    Input Parameters:
6437 .  mat - the matrix
6438 
6439    Output Parameters:
6440 +  m - the global index of the first local column
6441 -  n - one more than the global index of the last local column
6442 
6443    Notes:
6444     both output parameters can be NULL on input.
6445 
6446    Level: developer
6447 
6448    Concepts: matrices^column ownership
6449 
6450 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6451 
6452 @*/
6453 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6454 {
6455   PetscFunctionBegin;
6456   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6457   PetscValidType(mat,1);
6458   if (m) PetscValidIntPointer(m,2);
6459   if (n) PetscValidIntPointer(n,3);
6460   MatCheckPreallocated(mat,1);
6461   if (m) *m = mat->cmap->rstart;
6462   if (n) *n = mat->cmap->rend;
6463   PetscFunctionReturn(0);
6464 }
6465 
6466 /*@C
6467    MatGetOwnershipRange - Returns the range of matrix rows owned by
6468    this processor, assuming that the matrix is laid out with the first
6469    n1 rows on the first processor, the next n2 rows on the second, etc.
6470    For certain parallel layouts this range may not be well defined.
6471 
6472    Not Collective
6473 
6474    Input Parameters:
6475 .  mat - the matrix
6476 
6477    Output Parameters:
6478 +  m - the global index of the first local row
6479 -  n - one more than the global index of the last local row
6480 
6481    Note: Both output parameters can be NULL on input.
6482 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6483 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6484 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6485 
6486    Level: beginner
6487 
6488    Concepts: matrices^row ownership
6489 
6490 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6491 
6492 @*/
6493 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6494 {
6495   PetscFunctionBegin;
6496   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6497   PetscValidType(mat,1);
6498   if (m) PetscValidIntPointer(m,2);
6499   if (n) PetscValidIntPointer(n,3);
6500   MatCheckPreallocated(mat,1);
6501   if (m) *m = mat->rmap->rstart;
6502   if (n) *n = mat->rmap->rend;
6503   PetscFunctionReturn(0);
6504 }
6505 
6506 /*@C
6507    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6508    each process
6509 
6510    Not Collective, unless matrix has not been allocated, then collective on Mat
6511 
6512    Input Parameters:
6513 .  mat - the matrix
6514 
6515    Output Parameters:
6516 .  ranges - start of each processors portion plus one more than the total length at the end
6517 
6518    Level: beginner
6519 
6520    Concepts: matrices^row ownership
6521 
6522 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6523 
6524 @*/
6525 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6526 {
6527   PetscErrorCode ierr;
6528 
6529   PetscFunctionBegin;
6530   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6531   PetscValidType(mat,1);
6532   MatCheckPreallocated(mat,1);
6533   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6534   PetscFunctionReturn(0);
6535 }
6536 
6537 /*@C
6538    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6539    this processor. (The columns of the "diagonal blocks" for each process)
6540 
6541    Not Collective, unless matrix has not been allocated, then collective on Mat
6542 
6543    Input Parameters:
6544 .  mat - the matrix
6545 
6546    Output Parameters:
6547 .  ranges - start of each processors portion plus one more then the total length at the end
6548 
6549    Level: beginner
6550 
6551    Concepts: matrices^column ownership
6552 
6553 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6554 
6555 @*/
6556 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6557 {
6558   PetscErrorCode ierr;
6559 
6560   PetscFunctionBegin;
6561   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6562   PetscValidType(mat,1);
6563   MatCheckPreallocated(mat,1);
6564   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6565   PetscFunctionReturn(0);
6566 }
6567 
6568 /*@C
6569    MatGetOwnershipIS - Get row and column ownership as index sets
6570 
6571    Not Collective
6572 
6573    Input Arguments:
6574 .  A - matrix of type Elemental
6575 
6576    Output Arguments:
6577 +  rows - rows in which this process owns elements
6578 .  cols - columns in which this process owns elements
6579 
6580    Level: intermediate
6581 
6582 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6583 @*/
6584 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6585 {
6586   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6587 
6588   PetscFunctionBegin;
6589   MatCheckPreallocated(A,1);
6590   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6591   if (f) {
6592     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6593   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6594     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6595     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6596   }
6597   PetscFunctionReturn(0);
6598 }
6599 
6600 /*@C
6601    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6602    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6603    to complete the factorization.
6604 
6605    Collective on Mat
6606 
6607    Input Parameters:
6608 +  mat - the matrix
6609 .  row - row permutation
6610 .  column - column permutation
6611 -  info - structure containing
6612 $      levels - number of levels of fill.
6613 $      expected fill - as ratio of original fill.
6614 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6615                 missing diagonal entries)
6616 
6617    Output Parameters:
6618 .  fact - new matrix that has been symbolically factored
6619 
6620    Notes:
6621     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6622 
6623    Most users should employ the simplified KSP interface for linear solvers
6624    instead of working directly with matrix algebra routines such as this.
6625    See, e.g., KSPCreate().
6626 
6627    Level: developer
6628 
6629   Concepts: matrices^symbolic LU factorization
6630   Concepts: matrices^factorization
6631   Concepts: LU^symbolic factorization
6632 
6633 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6634           MatGetOrdering(), MatFactorInfo
6635 
6636     Developer Note: fortran interface is not autogenerated as the f90
6637     interface defintion cannot be generated correctly [due to MatFactorInfo]
6638 
6639 @*/
6640 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6641 {
6642   PetscErrorCode ierr;
6643 
6644   PetscFunctionBegin;
6645   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6646   PetscValidType(mat,1);
6647   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6648   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6649   PetscValidPointer(info,4);
6650   PetscValidPointer(fact,5);
6651   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6652   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6653   if (!(fact)->ops->ilufactorsymbolic) {
6654     MatSolverType spackage;
6655     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6656     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6657   }
6658   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6659   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6660   MatCheckPreallocated(mat,2);
6661 
6662   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6663   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6664   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6665   PetscFunctionReturn(0);
6666 }
6667 
6668 /*@C
6669    MatICCFactorSymbolic - Performs symbolic incomplete
6670    Cholesky factorization for a symmetric matrix.  Use
6671    MatCholeskyFactorNumeric() to complete the factorization.
6672 
6673    Collective on Mat
6674 
6675    Input Parameters:
6676 +  mat - the matrix
6677 .  perm - row and column permutation
6678 -  info - structure containing
6679 $      levels - number of levels of fill.
6680 $      expected fill - as ratio of original fill.
6681 
6682    Output Parameter:
6683 .  fact - the factored matrix
6684 
6685    Notes:
6686    Most users should employ the KSP interface for linear solvers
6687    instead of working directly with matrix algebra routines such as this.
6688    See, e.g., KSPCreate().
6689 
6690    Level: developer
6691 
6692   Concepts: matrices^symbolic incomplete Cholesky factorization
6693   Concepts: matrices^factorization
6694   Concepts: Cholsky^symbolic factorization
6695 
6696 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6697 
6698     Developer Note: fortran interface is not autogenerated as the f90
6699     interface defintion cannot be generated correctly [due to MatFactorInfo]
6700 
6701 @*/
6702 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6703 {
6704   PetscErrorCode ierr;
6705 
6706   PetscFunctionBegin;
6707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6708   PetscValidType(mat,1);
6709   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6710   PetscValidPointer(info,3);
6711   PetscValidPointer(fact,4);
6712   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6713   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6714   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6715   if (!(fact)->ops->iccfactorsymbolic) {
6716     MatSolverType spackage;
6717     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6718     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6719   }
6720   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6721   MatCheckPreallocated(mat,2);
6722 
6723   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6724   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6725   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6726   PetscFunctionReturn(0);
6727 }
6728 
6729 /*@C
6730    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6731    points to an array of valid matrices, they may be reused to store the new
6732    submatrices.
6733 
6734    Collective on Mat
6735 
6736    Input Parameters:
6737 +  mat - the matrix
6738 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6739 .  irow, icol - index sets of rows and columns to extract
6740 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6741 
6742    Output Parameter:
6743 .  submat - the array of submatrices
6744 
6745    Notes:
6746    MatCreateSubMatrices() can extract ONLY sequential submatrices
6747    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6748    to extract a parallel submatrix.
6749 
6750    Some matrix types place restrictions on the row and column
6751    indices, such as that they be sorted or that they be equal to each other.
6752 
6753    The index sets may not have duplicate entries.
6754 
6755    When extracting submatrices from a parallel matrix, each processor can
6756    form a different submatrix by setting the rows and columns of its
6757    individual index sets according to the local submatrix desired.
6758 
6759    When finished using the submatrices, the user should destroy
6760    them with MatDestroySubMatrices().
6761 
6762    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6763    original matrix has not changed from that last call to MatCreateSubMatrices().
6764 
6765    This routine creates the matrices in submat; you should NOT create them before
6766    calling it. It also allocates the array of matrix pointers submat.
6767 
6768    For BAIJ matrices the index sets must respect the block structure, that is if they
6769    request one row/column in a block, they must request all rows/columns that are in
6770    that block. For example, if the block size is 2 you cannot request just row 0 and
6771    column 0.
6772 
6773    Fortran Note:
6774    The Fortran interface is slightly different from that given below; it
6775    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6776 
6777    Level: advanced
6778 
6779    Concepts: matrices^accessing submatrices
6780    Concepts: submatrices
6781 
6782 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6783 @*/
6784 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6785 {
6786   PetscErrorCode ierr;
6787   PetscInt       i;
6788   PetscBool      eq;
6789 
6790   PetscFunctionBegin;
6791   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6792   PetscValidType(mat,1);
6793   if (n) {
6794     PetscValidPointer(irow,3);
6795     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6796     PetscValidPointer(icol,4);
6797     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6798   }
6799   PetscValidPointer(submat,6);
6800   if (n && scall == MAT_REUSE_MATRIX) {
6801     PetscValidPointer(*submat,6);
6802     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6803   }
6804   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6805   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6806   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6807   MatCheckPreallocated(mat,1);
6808 
6809   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6810   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6811   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6812   for (i=0; i<n; i++) {
6813     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6814     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6815       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6816       if (eq) {
6817         if (mat->symmetric) {
6818           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6819         } else if (mat->hermitian) {
6820           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6821         } else if (mat->structurally_symmetric) {
6822           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6823         }
6824       }
6825     }
6826   }
6827   PetscFunctionReturn(0);
6828 }
6829 
6830 /*@C
6831    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6832 
6833    Collective on Mat
6834 
6835    Input Parameters:
6836 +  mat - the matrix
6837 .  n   - the number of submatrixes to be extracted
6838 .  irow, icol - index sets of rows and columns to extract
6839 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6840 
6841    Output Parameter:
6842 .  submat - the array of submatrices
6843 
6844    Level: advanced
6845 
6846    Concepts: matrices^accessing submatrices
6847    Concepts: submatrices
6848 
6849 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6850 @*/
6851 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6852 {
6853   PetscErrorCode ierr;
6854   PetscInt       i;
6855   PetscBool      eq;
6856 
6857   PetscFunctionBegin;
6858   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6859   PetscValidType(mat,1);
6860   if (n) {
6861     PetscValidPointer(irow,3);
6862     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6863     PetscValidPointer(icol,4);
6864     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6865   }
6866   PetscValidPointer(submat,6);
6867   if (n && scall == MAT_REUSE_MATRIX) {
6868     PetscValidPointer(*submat,6);
6869     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6870   }
6871   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6872   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6873   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6874   MatCheckPreallocated(mat,1);
6875 
6876   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6877   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6878   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6879   for (i=0; i<n; i++) {
6880     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6881       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6882       if (eq) {
6883         if (mat->symmetric) {
6884           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6885         } else if (mat->hermitian) {
6886           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6887         } else if (mat->structurally_symmetric) {
6888           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6889         }
6890       }
6891     }
6892   }
6893   PetscFunctionReturn(0);
6894 }
6895 
6896 /*@C
6897    MatDestroyMatrices - Destroys an array of matrices.
6898 
6899    Collective on Mat
6900 
6901    Input Parameters:
6902 +  n - the number of local matrices
6903 -  mat - the matrices (note that this is a pointer to the array of matrices)
6904 
6905    Level: advanced
6906 
6907     Notes:
6908     Frees not only the matrices, but also the array that contains the matrices
6909            In Fortran will not free the array.
6910 
6911 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6912 @*/
6913 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6914 {
6915   PetscErrorCode ierr;
6916   PetscInt       i;
6917 
6918   PetscFunctionBegin;
6919   if (!*mat) PetscFunctionReturn(0);
6920   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6921   PetscValidPointer(mat,2);
6922 
6923   for (i=0; i<n; i++) {
6924     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6925   }
6926 
6927   /* memory is allocated even if n = 0 */
6928   ierr = PetscFree(*mat);CHKERRQ(ierr);
6929   PetscFunctionReturn(0);
6930 }
6931 
6932 /*@C
6933    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6934 
6935    Collective on Mat
6936 
6937    Input Parameters:
6938 +  n - the number of local matrices
6939 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6940                        sequence of MatCreateSubMatrices())
6941 
6942    Level: advanced
6943 
6944     Notes:
6945     Frees not only the matrices, but also the array that contains the matrices
6946            In Fortran will not free the array.
6947 
6948 .seealso: MatCreateSubMatrices()
6949 @*/
6950 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6951 {
6952   PetscErrorCode ierr;
6953   Mat            mat0;
6954 
6955   PetscFunctionBegin;
6956   if (!*mat) PetscFunctionReturn(0);
6957   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6958   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6959   PetscValidPointer(mat,2);
6960 
6961   mat0 = (*mat)[0];
6962   if (mat0 && mat0->ops->destroysubmatrices) {
6963     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6964   } else {
6965     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6966   }
6967   PetscFunctionReturn(0);
6968 }
6969 
6970 /*@C
6971    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6972 
6973    Collective on Mat
6974 
6975    Input Parameters:
6976 .  mat - the matrix
6977 
6978    Output Parameter:
6979 .  matstruct - the sequential matrix with the nonzero structure of mat
6980 
6981   Level: intermediate
6982 
6983 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6984 @*/
6985 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6986 {
6987   PetscErrorCode ierr;
6988 
6989   PetscFunctionBegin;
6990   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6991   PetscValidPointer(matstruct,2);
6992 
6993   PetscValidType(mat,1);
6994   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6995   MatCheckPreallocated(mat,1);
6996 
6997   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6998   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6999   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7000   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7001   PetscFunctionReturn(0);
7002 }
7003 
7004 /*@C
7005    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7006 
7007    Collective on Mat
7008 
7009    Input Parameters:
7010 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7011                        sequence of MatGetSequentialNonzeroStructure())
7012 
7013    Level: advanced
7014 
7015     Notes:
7016     Frees not only the matrices, but also the array that contains the matrices
7017 
7018 .seealso: MatGetSeqNonzeroStructure()
7019 @*/
7020 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7021 {
7022   PetscErrorCode ierr;
7023 
7024   PetscFunctionBegin;
7025   PetscValidPointer(mat,1);
7026   ierr = MatDestroy(mat);CHKERRQ(ierr);
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 /*@
7031    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7032    replaces the index sets by larger ones that represent submatrices with
7033    additional overlap.
7034 
7035    Collective on Mat
7036 
7037    Input Parameters:
7038 +  mat - the matrix
7039 .  n   - the number of index sets
7040 .  is  - the array of index sets (these index sets will changed during the call)
7041 -  ov  - the additional overlap requested
7042 
7043    Options Database:
7044 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7045 
7046    Level: developer
7047 
7048    Concepts: overlap
7049    Concepts: ASM^computing overlap
7050 
7051 .seealso: MatCreateSubMatrices()
7052 @*/
7053 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7054 {
7055   PetscErrorCode ierr;
7056 
7057   PetscFunctionBegin;
7058   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7059   PetscValidType(mat,1);
7060   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7061   if (n) {
7062     PetscValidPointer(is,3);
7063     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7064   }
7065   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7066   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7067   MatCheckPreallocated(mat,1);
7068 
7069   if (!ov) PetscFunctionReturn(0);
7070   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7071   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7072   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7073   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7074   PetscFunctionReturn(0);
7075 }
7076 
7077 
7078 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7079 
7080 /*@
7081    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7082    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7083    additional overlap.
7084 
7085    Collective on Mat
7086 
7087    Input Parameters:
7088 +  mat - the matrix
7089 .  n   - the number of index sets
7090 .  is  - the array of index sets (these index sets will changed during the call)
7091 -  ov  - the additional overlap requested
7092 
7093    Options Database:
7094 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7095 
7096    Level: developer
7097 
7098    Concepts: overlap
7099    Concepts: ASM^computing overlap
7100 
7101 .seealso: MatCreateSubMatrices()
7102 @*/
7103 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7104 {
7105   PetscInt       i;
7106   PetscErrorCode ierr;
7107 
7108   PetscFunctionBegin;
7109   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7110   PetscValidType(mat,1);
7111   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7112   if (n) {
7113     PetscValidPointer(is,3);
7114     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7115   }
7116   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7117   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7118   MatCheckPreallocated(mat,1);
7119   if (!ov) PetscFunctionReturn(0);
7120   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7121   for(i=0; i<n; i++){
7122 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7123   }
7124   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7125   PetscFunctionReturn(0);
7126 }
7127 
7128 
7129 
7130 
7131 /*@
7132    MatGetBlockSize - Returns the matrix block size.
7133 
7134    Not Collective
7135 
7136    Input Parameter:
7137 .  mat - the matrix
7138 
7139    Output Parameter:
7140 .  bs - block size
7141 
7142    Notes:
7143     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7144 
7145    If the block size has not been set yet this routine returns 1.
7146 
7147    Level: intermediate
7148 
7149    Concepts: matrices^block size
7150 
7151 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7152 @*/
7153 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7154 {
7155   PetscFunctionBegin;
7156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7157   PetscValidIntPointer(bs,2);
7158   *bs = PetscAbs(mat->rmap->bs);
7159   PetscFunctionReturn(0);
7160 }
7161 
7162 /*@
7163    MatGetBlockSizes - Returns the matrix block row and column sizes.
7164 
7165    Not Collective
7166 
7167    Input Parameter:
7168 .  mat - the matrix
7169 
7170    Output Parameter:
7171 .  rbs - row block size
7172 .  cbs - column block size
7173 
7174    Notes:
7175     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7176     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7177 
7178    If a block size has not been set yet this routine returns 1.
7179 
7180    Level: intermediate
7181 
7182    Concepts: matrices^block size
7183 
7184 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7185 @*/
7186 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7187 {
7188   PetscFunctionBegin;
7189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7190   if (rbs) PetscValidIntPointer(rbs,2);
7191   if (cbs) PetscValidIntPointer(cbs,3);
7192   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7193   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7194   PetscFunctionReturn(0);
7195 }
7196 
7197 /*@
7198    MatSetBlockSize - Sets the matrix block size.
7199 
7200    Logically Collective on Mat
7201 
7202    Input Parameters:
7203 +  mat - the matrix
7204 -  bs - block size
7205 
7206    Notes:
7207     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7208     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7209 
7210     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7211     is compatible with the matrix local sizes.
7212 
7213    Level: intermediate
7214 
7215    Concepts: matrices^block size
7216 
7217 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7218 @*/
7219 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7220 {
7221   PetscErrorCode ierr;
7222 
7223   PetscFunctionBegin;
7224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7225   PetscValidLogicalCollectiveInt(mat,bs,2);
7226   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7227   PetscFunctionReturn(0);
7228 }
7229 
7230 /*@
7231    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7232 
7233    Logically Collective on Mat
7234 
7235    Input Parameters:
7236 +  mat - the matrix
7237 .  nblocks - the number of blocks on this process
7238 -  bsizes - the block sizes
7239 
7240    Notes:
7241     Currently used by PCVPBJACOBI for SeqAIJ matrices
7242 
7243    Level: intermediate
7244 
7245    Concepts: matrices^block size
7246 
7247 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7248 @*/
7249 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7250 {
7251   PetscErrorCode ierr;
7252   PetscInt       i,ncnt = 0, nlocal;
7253 
7254   PetscFunctionBegin;
7255   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7256   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7257   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7258   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7259   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);
7260   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7261   mat->nblocks = nblocks;
7262   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7263   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7264   PetscFunctionReturn(0);
7265 }
7266 
7267 /*@C
7268    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7269 
7270    Logically Collective on Mat
7271 
7272    Input Parameters:
7273 .  mat - the matrix
7274 
7275    Output Parameters:
7276 +  nblocks - the number of blocks on this process
7277 -  bsizes - the block sizes
7278 
7279    Notes: Currently not supported from Fortran
7280 
7281    Level: intermediate
7282 
7283    Concepts: matrices^block size
7284 
7285 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7286 @*/
7287 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7288 {
7289   PetscFunctionBegin;
7290   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7291   *nblocks = mat->nblocks;
7292   *bsizes  = mat->bsizes;
7293   PetscFunctionReturn(0);
7294 }
7295 
7296 /*@
7297    MatSetBlockSizes - Sets the matrix block row and column sizes.
7298 
7299    Logically Collective on Mat
7300 
7301    Input Parameters:
7302 +  mat - the matrix
7303 -  rbs - row block size
7304 -  cbs - column block size
7305 
7306    Notes:
7307     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7308     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7309     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7310 
7311     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7312     are compatible with the matrix local sizes.
7313 
7314     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7315 
7316    Level: intermediate
7317 
7318    Concepts: matrices^block size
7319 
7320 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7321 @*/
7322 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7323 {
7324   PetscErrorCode ierr;
7325 
7326   PetscFunctionBegin;
7327   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7328   PetscValidLogicalCollectiveInt(mat,rbs,2);
7329   PetscValidLogicalCollectiveInt(mat,cbs,3);
7330   if (mat->ops->setblocksizes) {
7331     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7332   }
7333   if (mat->rmap->refcnt) {
7334     ISLocalToGlobalMapping l2g = NULL;
7335     PetscLayout            nmap = NULL;
7336 
7337     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7338     if (mat->rmap->mapping) {
7339       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7340     }
7341     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7342     mat->rmap = nmap;
7343     mat->rmap->mapping = l2g;
7344   }
7345   if (mat->cmap->refcnt) {
7346     ISLocalToGlobalMapping l2g = NULL;
7347     PetscLayout            nmap = NULL;
7348 
7349     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7350     if (mat->cmap->mapping) {
7351       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7352     }
7353     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7354     mat->cmap = nmap;
7355     mat->cmap->mapping = l2g;
7356   }
7357   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7358   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7359   PetscFunctionReturn(0);
7360 }
7361 
7362 /*@
7363    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7364 
7365    Logically Collective on Mat
7366 
7367    Input Parameters:
7368 +  mat - the matrix
7369 .  fromRow - matrix from which to copy row block size
7370 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7371 
7372    Level: developer
7373 
7374    Concepts: matrices^block size
7375 
7376 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7377 @*/
7378 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7379 {
7380   PetscErrorCode ierr;
7381 
7382   PetscFunctionBegin;
7383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7384   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7385   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7386   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7387   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7388   PetscFunctionReturn(0);
7389 }
7390 
7391 /*@
7392    MatResidual - Default routine to calculate the residual.
7393 
7394    Collective on Mat and Vec
7395 
7396    Input Parameters:
7397 +  mat - the matrix
7398 .  b   - the right-hand-side
7399 -  x   - the approximate solution
7400 
7401    Output Parameter:
7402 .  r - location to store the residual
7403 
7404    Level: developer
7405 
7406 .keywords: MG, default, multigrid, residual
7407 
7408 .seealso: PCMGSetResidual()
7409 @*/
7410 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7411 {
7412   PetscErrorCode ierr;
7413 
7414   PetscFunctionBegin;
7415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7416   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7417   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7418   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7419   PetscValidType(mat,1);
7420   MatCheckPreallocated(mat,1);
7421   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7422   if (!mat->ops->residual) {
7423     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7424     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7425   } else {
7426     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7427   }
7428   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7429   PetscFunctionReturn(0);
7430 }
7431 
7432 /*@C
7433     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7434 
7435    Collective on Mat
7436 
7437     Input Parameters:
7438 +   mat - the matrix
7439 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7440 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7441 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7442                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7443                  always used.
7444 
7445     Output Parameters:
7446 +   n - number of rows in the (possibly compressed) matrix
7447 .   ia - the row pointers [of length n+1]
7448 .   ja - the column indices
7449 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7450            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7451 
7452     Level: developer
7453 
7454     Notes:
7455     You CANNOT change any of the ia[] or ja[] values.
7456 
7457     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7458 
7459     Fortran Notes:
7460     In Fortran use
7461 $
7462 $      PetscInt ia(1), ja(1)
7463 $      PetscOffset iia, jja
7464 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7465 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7466 
7467      or
7468 $
7469 $    PetscInt, pointer :: ia(:),ja(:)
7470 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7471 $    ! Access the ith and jth entries via ia(i) and ja(j)
7472 
7473 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7474 @*/
7475 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7476 {
7477   PetscErrorCode ierr;
7478 
7479   PetscFunctionBegin;
7480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7481   PetscValidType(mat,1);
7482   PetscValidIntPointer(n,5);
7483   if (ia) PetscValidIntPointer(ia,6);
7484   if (ja) PetscValidIntPointer(ja,7);
7485   PetscValidIntPointer(done,8);
7486   MatCheckPreallocated(mat,1);
7487   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7488   else {
7489     *done = PETSC_TRUE;
7490     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7491     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7492     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7493   }
7494   PetscFunctionReturn(0);
7495 }
7496 
7497 /*@C
7498     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7499 
7500     Collective on Mat
7501 
7502     Input Parameters:
7503 +   mat - the matrix
7504 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7505 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7506                 symmetrized
7507 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7508                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7509                  always used.
7510 .   n - number of columns in the (possibly compressed) matrix
7511 .   ia - the column pointers
7512 -   ja - the row indices
7513 
7514     Output Parameters:
7515 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7516 
7517     Note:
7518     This routine zeros out n, ia, and ja. This is to prevent accidental
7519     us of the array after it has been restored. If you pass NULL, it will
7520     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7521 
7522     Level: developer
7523 
7524 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7525 @*/
7526 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7527 {
7528   PetscErrorCode ierr;
7529 
7530   PetscFunctionBegin;
7531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7532   PetscValidType(mat,1);
7533   PetscValidIntPointer(n,4);
7534   if (ia) PetscValidIntPointer(ia,5);
7535   if (ja) PetscValidIntPointer(ja,6);
7536   PetscValidIntPointer(done,7);
7537   MatCheckPreallocated(mat,1);
7538   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7539   else {
7540     *done = PETSC_TRUE;
7541     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7542   }
7543   PetscFunctionReturn(0);
7544 }
7545 
7546 /*@C
7547     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7548     MatGetRowIJ().
7549 
7550     Collective on Mat
7551 
7552     Input Parameters:
7553 +   mat - the matrix
7554 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7555 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7556                 symmetrized
7557 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7558                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7559                  always used.
7560 .   n - size of (possibly compressed) matrix
7561 .   ia - the row pointers
7562 -   ja - the column indices
7563 
7564     Output Parameters:
7565 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7566 
7567     Note:
7568     This routine zeros out n, ia, and ja. This is to prevent accidental
7569     us of the array after it has been restored. If you pass NULL, it will
7570     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7571 
7572     Level: developer
7573 
7574 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7575 @*/
7576 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7577 {
7578   PetscErrorCode ierr;
7579 
7580   PetscFunctionBegin;
7581   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7582   PetscValidType(mat,1);
7583   if (ia) PetscValidIntPointer(ia,6);
7584   if (ja) PetscValidIntPointer(ja,7);
7585   PetscValidIntPointer(done,8);
7586   MatCheckPreallocated(mat,1);
7587 
7588   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7589   else {
7590     *done = PETSC_TRUE;
7591     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7592     if (n)  *n = 0;
7593     if (ia) *ia = NULL;
7594     if (ja) *ja = NULL;
7595   }
7596   PetscFunctionReturn(0);
7597 }
7598 
7599 /*@C
7600     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7601     MatGetColumnIJ().
7602 
7603     Collective on Mat
7604 
7605     Input Parameters:
7606 +   mat - the matrix
7607 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7608 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7609                 symmetrized
7610 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7611                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7612                  always used.
7613 
7614     Output Parameters:
7615 +   n - size of (possibly compressed) matrix
7616 .   ia - the column pointers
7617 .   ja - the row indices
7618 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7619 
7620     Level: developer
7621 
7622 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7623 @*/
7624 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7625 {
7626   PetscErrorCode ierr;
7627 
7628   PetscFunctionBegin;
7629   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7630   PetscValidType(mat,1);
7631   if (ia) PetscValidIntPointer(ia,5);
7632   if (ja) PetscValidIntPointer(ja,6);
7633   PetscValidIntPointer(done,7);
7634   MatCheckPreallocated(mat,1);
7635 
7636   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7637   else {
7638     *done = PETSC_TRUE;
7639     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7640     if (n)  *n = 0;
7641     if (ia) *ia = NULL;
7642     if (ja) *ja = NULL;
7643   }
7644   PetscFunctionReturn(0);
7645 }
7646 
7647 /*@C
7648     MatColoringPatch -Used inside matrix coloring routines that
7649     use MatGetRowIJ() and/or MatGetColumnIJ().
7650 
7651     Collective on Mat
7652 
7653     Input Parameters:
7654 +   mat - the matrix
7655 .   ncolors - max color value
7656 .   n   - number of entries in colorarray
7657 -   colorarray - array indicating color for each column
7658 
7659     Output Parameters:
7660 .   iscoloring - coloring generated using colorarray information
7661 
7662     Level: developer
7663 
7664 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7665 
7666 @*/
7667 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7668 {
7669   PetscErrorCode ierr;
7670 
7671   PetscFunctionBegin;
7672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7673   PetscValidType(mat,1);
7674   PetscValidIntPointer(colorarray,4);
7675   PetscValidPointer(iscoloring,5);
7676   MatCheckPreallocated(mat,1);
7677 
7678   if (!mat->ops->coloringpatch) {
7679     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7680   } else {
7681     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7682   }
7683   PetscFunctionReturn(0);
7684 }
7685 
7686 
7687 /*@
7688    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7689 
7690    Logically Collective on Mat
7691 
7692    Input Parameter:
7693 .  mat - the factored matrix to be reset
7694 
7695    Notes:
7696    This routine should be used only with factored matrices formed by in-place
7697    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7698    format).  This option can save memory, for example, when solving nonlinear
7699    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7700    ILU(0) preconditioner.
7701 
7702    Note that one can specify in-place ILU(0) factorization by calling
7703 .vb
7704      PCType(pc,PCILU);
7705      PCFactorSeUseInPlace(pc);
7706 .ve
7707    or by using the options -pc_type ilu -pc_factor_in_place
7708 
7709    In-place factorization ILU(0) can also be used as a local
7710    solver for the blocks within the block Jacobi or additive Schwarz
7711    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7712    for details on setting local solver options.
7713 
7714    Most users should employ the simplified KSP interface for linear solvers
7715    instead of working directly with matrix algebra routines such as this.
7716    See, e.g., KSPCreate().
7717 
7718    Level: developer
7719 
7720 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7721 
7722    Concepts: matrices^unfactored
7723 
7724 @*/
7725 PetscErrorCode MatSetUnfactored(Mat mat)
7726 {
7727   PetscErrorCode ierr;
7728 
7729   PetscFunctionBegin;
7730   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7731   PetscValidType(mat,1);
7732   MatCheckPreallocated(mat,1);
7733   mat->factortype = MAT_FACTOR_NONE;
7734   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7735   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7736   PetscFunctionReturn(0);
7737 }
7738 
7739 /*MC
7740     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7741 
7742     Synopsis:
7743     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7744 
7745     Not collective
7746 
7747     Input Parameter:
7748 .   x - matrix
7749 
7750     Output Parameters:
7751 +   xx_v - the Fortran90 pointer to the array
7752 -   ierr - error code
7753 
7754     Example of Usage:
7755 .vb
7756       PetscScalar, pointer xx_v(:,:)
7757       ....
7758       call MatDenseGetArrayF90(x,xx_v,ierr)
7759       a = xx_v(3)
7760       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7761 .ve
7762 
7763     Level: advanced
7764 
7765 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7766 
7767     Concepts: matrices^accessing array
7768 
7769 M*/
7770 
7771 /*MC
7772     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7773     accessed with MatDenseGetArrayF90().
7774 
7775     Synopsis:
7776     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7777 
7778     Not collective
7779 
7780     Input Parameters:
7781 +   x - matrix
7782 -   xx_v - the Fortran90 pointer to the array
7783 
7784     Output Parameter:
7785 .   ierr - error code
7786 
7787     Example of Usage:
7788 .vb
7789        PetscScalar, pointer xx_v(:,:)
7790        ....
7791        call MatDenseGetArrayF90(x,xx_v,ierr)
7792        a = xx_v(3)
7793        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7794 .ve
7795 
7796     Level: advanced
7797 
7798 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7799 
7800 M*/
7801 
7802 
7803 /*MC
7804     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7805 
7806     Synopsis:
7807     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7808 
7809     Not collective
7810 
7811     Input Parameter:
7812 .   x - matrix
7813 
7814     Output Parameters:
7815 +   xx_v - the Fortran90 pointer to the array
7816 -   ierr - error code
7817 
7818     Example of Usage:
7819 .vb
7820       PetscScalar, pointer xx_v(:)
7821       ....
7822       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7823       a = xx_v(3)
7824       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7825 .ve
7826 
7827     Level: advanced
7828 
7829 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7830 
7831     Concepts: matrices^accessing array
7832 
7833 M*/
7834 
7835 /*MC
7836     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7837     accessed with MatSeqAIJGetArrayF90().
7838 
7839     Synopsis:
7840     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7841 
7842     Not collective
7843 
7844     Input Parameters:
7845 +   x - matrix
7846 -   xx_v - the Fortran90 pointer to the array
7847 
7848     Output Parameter:
7849 .   ierr - error code
7850 
7851     Example of Usage:
7852 .vb
7853        PetscScalar, pointer xx_v(:)
7854        ....
7855        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7856        a = xx_v(3)
7857        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7858 .ve
7859 
7860     Level: advanced
7861 
7862 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7863 
7864 M*/
7865 
7866 
7867 /*@
7868     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7869                       as the original matrix.
7870 
7871     Collective on Mat
7872 
7873     Input Parameters:
7874 +   mat - the original matrix
7875 .   isrow - parallel IS containing the rows this processor should obtain
7876 .   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.
7877 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7878 
7879     Output Parameter:
7880 .   newmat - the new submatrix, of the same type as the old
7881 
7882     Level: advanced
7883 
7884     Notes:
7885     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7886 
7887     Some matrix types place restrictions on the row and column indices, such
7888     as that they be sorted or that they be equal to each other.
7889 
7890     The index sets may not have duplicate entries.
7891 
7892       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7893    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7894    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7895    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7896    you are finished using it.
7897 
7898     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7899     the input matrix.
7900 
7901     If iscol is NULL then all columns are obtained (not supported in Fortran).
7902 
7903    Example usage:
7904    Consider the following 8x8 matrix with 34 non-zero values, that is
7905    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7906    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7907    as follows:
7908 
7909 .vb
7910             1  2  0  |  0  3  0  |  0  4
7911     Proc0   0  5  6  |  7  0  0  |  8  0
7912             9  0 10  | 11  0  0  | 12  0
7913     -------------------------------------
7914            13  0 14  | 15 16 17  |  0  0
7915     Proc1   0 18  0  | 19 20 21  |  0  0
7916             0  0  0  | 22 23  0  | 24  0
7917     -------------------------------------
7918     Proc2  25 26 27  |  0  0 28  | 29  0
7919            30  0  0  | 31 32 33  |  0 34
7920 .ve
7921 
7922     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7923 
7924 .vb
7925             2  0  |  0  3  0  |  0
7926     Proc0   5  6  |  7  0  0  |  8
7927     -------------------------------
7928     Proc1  18  0  | 19 20 21  |  0
7929     -------------------------------
7930     Proc2  26 27  |  0  0 28  | 29
7931             0  0  | 31 32 33  |  0
7932 .ve
7933 
7934 
7935     Concepts: matrices^submatrices
7936 
7937 .seealso: MatCreateSubMatrices()
7938 @*/
7939 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7940 {
7941   PetscErrorCode ierr;
7942   PetscMPIInt    size;
7943   Mat            *local;
7944   IS             iscoltmp;
7945 
7946   PetscFunctionBegin;
7947   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7948   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7949   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7950   PetscValidPointer(newmat,5);
7951   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7952   PetscValidType(mat,1);
7953   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7954   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7955 
7956   MatCheckPreallocated(mat,1);
7957   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7958 
7959   if (!iscol || isrow == iscol) {
7960     PetscBool   stride;
7961     PetscMPIInt grabentirematrix = 0,grab;
7962     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7963     if (stride) {
7964       PetscInt first,step,n,rstart,rend;
7965       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7966       if (step == 1) {
7967         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7968         if (rstart == first) {
7969           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7970           if (n == rend-rstart) {
7971             grabentirematrix = 1;
7972           }
7973         }
7974       }
7975     }
7976     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7977     if (grab) {
7978       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7979       if (cll == MAT_INITIAL_MATRIX) {
7980         *newmat = mat;
7981         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7982       }
7983       PetscFunctionReturn(0);
7984     }
7985   }
7986 
7987   if (!iscol) {
7988     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7989   } else {
7990     iscoltmp = iscol;
7991   }
7992 
7993   /* if original matrix is on just one processor then use submatrix generated */
7994   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7995     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7996     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7997     PetscFunctionReturn(0);
7998   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7999     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8000     *newmat = *local;
8001     ierr    = PetscFree(local);CHKERRQ(ierr);
8002     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8003     PetscFunctionReturn(0);
8004   } else if (!mat->ops->createsubmatrix) {
8005     /* Create a new matrix type that implements the operation using the full matrix */
8006     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8007     switch (cll) {
8008     case MAT_INITIAL_MATRIX:
8009       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8010       break;
8011     case MAT_REUSE_MATRIX:
8012       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8013       break;
8014     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8015     }
8016     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8017     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8018     PetscFunctionReturn(0);
8019   }
8020 
8021   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8022   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8023   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8024   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8025 
8026   /* Propagate symmetry information for diagonal blocks */
8027   if (isrow == iscoltmp) {
8028     if (mat->symmetric_set && mat->symmetric) {
8029       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8030     }
8031     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8032       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8033     }
8034     if (mat->hermitian_set && mat->hermitian) {
8035       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8036     }
8037     if (mat->spd_set && mat->spd) {
8038       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8039     }
8040   }
8041 
8042   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8043   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8044   PetscFunctionReturn(0);
8045 }
8046 
8047 /*@
8048    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8049    used during the assembly process to store values that belong to
8050    other processors.
8051 
8052    Not Collective
8053 
8054    Input Parameters:
8055 +  mat   - the matrix
8056 .  size  - the initial size of the stash.
8057 -  bsize - the initial size of the block-stash(if used).
8058 
8059    Options Database Keys:
8060 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8061 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8062 
8063    Level: intermediate
8064 
8065    Notes:
8066      The block-stash is used for values set with MatSetValuesBlocked() while
8067      the stash is used for values set with MatSetValues()
8068 
8069      Run with the option -info and look for output of the form
8070      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8071      to determine the appropriate value, MM, to use for size and
8072      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8073      to determine the value, BMM to use for bsize
8074 
8075    Concepts: stash^setting matrix size
8076    Concepts: matrices^stash
8077 
8078 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8079 
8080 @*/
8081 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8082 {
8083   PetscErrorCode ierr;
8084 
8085   PetscFunctionBegin;
8086   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8087   PetscValidType(mat,1);
8088   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8089   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8090   PetscFunctionReturn(0);
8091 }
8092 
8093 /*@
8094    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8095      the matrix
8096 
8097    Neighbor-wise Collective on Mat
8098 
8099    Input Parameters:
8100 +  mat   - the matrix
8101 .  x,y - the vectors
8102 -  w - where the result is stored
8103 
8104    Level: intermediate
8105 
8106    Notes:
8107     w may be the same vector as y.
8108 
8109     This allows one to use either the restriction or interpolation (its transpose)
8110     matrix to do the interpolation
8111 
8112     Concepts: interpolation
8113 
8114 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8115 
8116 @*/
8117 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8118 {
8119   PetscErrorCode ierr;
8120   PetscInt       M,N,Ny;
8121 
8122   PetscFunctionBegin;
8123   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8124   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8125   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8126   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8127   PetscValidType(A,1);
8128   MatCheckPreallocated(A,1);
8129   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8130   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8131   if (M == Ny) {
8132     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8133   } else {
8134     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8135   }
8136   PetscFunctionReturn(0);
8137 }
8138 
8139 /*@
8140    MatInterpolate - y = A*x or A'*x depending on the shape of
8141      the matrix
8142 
8143    Neighbor-wise Collective on Mat
8144 
8145    Input Parameters:
8146 +  mat   - the matrix
8147 -  x,y - the vectors
8148 
8149    Level: intermediate
8150 
8151    Notes:
8152     This allows one to use either the restriction or interpolation (its transpose)
8153     matrix to do the interpolation
8154 
8155    Concepts: matrices^interpolation
8156 
8157 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8158 
8159 @*/
8160 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8161 {
8162   PetscErrorCode ierr;
8163   PetscInt       M,N,Ny;
8164 
8165   PetscFunctionBegin;
8166   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8167   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8168   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8169   PetscValidType(A,1);
8170   MatCheckPreallocated(A,1);
8171   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8172   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8173   if (M == Ny) {
8174     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8175   } else {
8176     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8177   }
8178   PetscFunctionReturn(0);
8179 }
8180 
8181 /*@
8182    MatRestrict - y = A*x or A'*x
8183 
8184    Neighbor-wise Collective on Mat
8185 
8186    Input Parameters:
8187 +  mat   - the matrix
8188 -  x,y - the vectors
8189 
8190    Level: intermediate
8191 
8192    Notes:
8193     This allows one to use either the restriction or interpolation (its transpose)
8194     matrix to do the restriction
8195 
8196    Concepts: matrices^restriction
8197 
8198 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8199 
8200 @*/
8201 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8202 {
8203   PetscErrorCode ierr;
8204   PetscInt       M,N,Ny;
8205 
8206   PetscFunctionBegin;
8207   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8208   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8209   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8210   PetscValidType(A,1);
8211   MatCheckPreallocated(A,1);
8212 
8213   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8214   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8215   if (M == Ny) {
8216     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8217   } else {
8218     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8219   }
8220   PetscFunctionReturn(0);
8221 }
8222 
8223 /*@
8224    MatGetNullSpace - retrieves the null space of a matrix.
8225 
8226    Logically Collective on Mat and MatNullSpace
8227 
8228    Input Parameters:
8229 +  mat - the matrix
8230 -  nullsp - the null space object
8231 
8232    Level: developer
8233 
8234    Concepts: null space^attaching to matrix
8235 
8236 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8237 @*/
8238 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8239 {
8240   PetscFunctionBegin;
8241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8242   PetscValidPointer(nullsp,2);
8243   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8244   PetscFunctionReturn(0);
8245 }
8246 
8247 /*@
8248    MatSetNullSpace - attaches a null space to a matrix.
8249 
8250    Logically Collective on Mat and MatNullSpace
8251 
8252    Input Parameters:
8253 +  mat - the matrix
8254 -  nullsp - the null space object
8255 
8256    Level: advanced
8257 
8258    Notes:
8259       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8260 
8261       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8262       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8263 
8264       You can remove the null space by calling this routine with an nullsp of NULL
8265 
8266 
8267       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8268    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).
8269    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
8270    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
8271    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).
8272 
8273       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8274 
8275     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
8276     routine also automatically calls MatSetTransposeNullSpace().
8277 
8278    Concepts: null space^attaching to matrix
8279 
8280 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8281 @*/
8282 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8283 {
8284   PetscErrorCode ierr;
8285 
8286   PetscFunctionBegin;
8287   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8288   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8289   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8290   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8291   mat->nullsp = nullsp;
8292   if (mat->symmetric_set && mat->symmetric) {
8293     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8294   }
8295   PetscFunctionReturn(0);
8296 }
8297 
8298 /*@
8299    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8300 
8301    Logically Collective on Mat and MatNullSpace
8302 
8303    Input Parameters:
8304 +  mat - the matrix
8305 -  nullsp - the null space object
8306 
8307    Level: developer
8308 
8309    Concepts: null space^attaching to matrix
8310 
8311 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8312 @*/
8313 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8314 {
8315   PetscFunctionBegin;
8316   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8317   PetscValidType(mat,1);
8318   PetscValidPointer(nullsp,2);
8319   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8320   PetscFunctionReturn(0);
8321 }
8322 
8323 /*@
8324    MatSetTransposeNullSpace - attaches a null space to a matrix.
8325 
8326    Logically Collective on Mat and MatNullSpace
8327 
8328    Input Parameters:
8329 +  mat - the matrix
8330 -  nullsp - the null space object
8331 
8332    Level: advanced
8333 
8334    Notes:
8335       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.
8336       You must also call MatSetNullSpace()
8337 
8338 
8339       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8340    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).
8341    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
8342    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
8343    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).
8344 
8345       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8346 
8347    Concepts: null space^attaching to matrix
8348 
8349 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8350 @*/
8351 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8352 {
8353   PetscErrorCode ierr;
8354 
8355   PetscFunctionBegin;
8356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8357   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8358   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8359   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8360   mat->transnullsp = nullsp;
8361   PetscFunctionReturn(0);
8362 }
8363 
8364 /*@
8365    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8366         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8367 
8368    Logically Collective on Mat and MatNullSpace
8369 
8370    Input Parameters:
8371 +  mat - the matrix
8372 -  nullsp - the null space object
8373 
8374    Level: advanced
8375 
8376    Notes:
8377       Overwrites any previous near null space that may have been attached
8378 
8379       You can remove the null space by calling this routine with an nullsp of NULL
8380 
8381    Concepts: null space^attaching to matrix
8382 
8383 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8384 @*/
8385 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8386 {
8387   PetscErrorCode ierr;
8388 
8389   PetscFunctionBegin;
8390   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8391   PetscValidType(mat,1);
8392   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8393   MatCheckPreallocated(mat,1);
8394   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8395   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8396   mat->nearnullsp = nullsp;
8397   PetscFunctionReturn(0);
8398 }
8399 
8400 /*@
8401    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8402 
8403    Not Collective
8404 
8405    Input Parameters:
8406 .  mat - the matrix
8407 
8408    Output Parameters:
8409 .  nullsp - the null space object, NULL if not set
8410 
8411    Level: developer
8412 
8413    Concepts: null space^attaching to matrix
8414 
8415 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8416 @*/
8417 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8418 {
8419   PetscFunctionBegin;
8420   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8421   PetscValidType(mat,1);
8422   PetscValidPointer(nullsp,2);
8423   MatCheckPreallocated(mat,1);
8424   *nullsp = mat->nearnullsp;
8425   PetscFunctionReturn(0);
8426 }
8427 
8428 /*@C
8429    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8430 
8431    Collective on Mat
8432 
8433    Input Parameters:
8434 +  mat - the matrix
8435 .  row - row/column permutation
8436 .  fill - expected fill factor >= 1.0
8437 -  level - level of fill, for ICC(k)
8438 
8439    Notes:
8440    Probably really in-place only when level of fill is zero, otherwise allocates
8441    new space to store factored matrix and deletes previous memory.
8442 
8443    Most users should employ the simplified KSP interface for linear solvers
8444    instead of working directly with matrix algebra routines such as this.
8445    See, e.g., KSPCreate().
8446 
8447    Level: developer
8448 
8449    Concepts: matrices^incomplete Cholesky factorization
8450    Concepts: Cholesky factorization
8451 
8452 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8453 
8454     Developer Note: fortran interface is not autogenerated as the f90
8455     interface defintion cannot be generated correctly [due to MatFactorInfo]
8456 
8457 @*/
8458 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8459 {
8460   PetscErrorCode ierr;
8461 
8462   PetscFunctionBegin;
8463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8464   PetscValidType(mat,1);
8465   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8466   PetscValidPointer(info,3);
8467   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8468   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8469   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8470   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8471   MatCheckPreallocated(mat,1);
8472   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8473   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8474   PetscFunctionReturn(0);
8475 }
8476 
8477 /*@
8478    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8479          ghosted ones.
8480 
8481    Not Collective
8482 
8483    Input Parameters:
8484 +  mat - the matrix
8485 -  diag = the diagonal values, including ghost ones
8486 
8487    Level: developer
8488 
8489    Notes:
8490     Works only for MPIAIJ and MPIBAIJ matrices
8491 
8492 .seealso: MatDiagonalScale()
8493 @*/
8494 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8495 {
8496   PetscErrorCode ierr;
8497   PetscMPIInt    size;
8498 
8499   PetscFunctionBegin;
8500   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8501   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8502   PetscValidType(mat,1);
8503 
8504   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8505   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8506   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8507   if (size == 1) {
8508     PetscInt n,m;
8509     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8510     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8511     if (m == n) {
8512       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8513     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8514   } else {
8515     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8516   }
8517   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8518   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8519   PetscFunctionReturn(0);
8520 }
8521 
8522 /*@
8523    MatGetInertia - Gets the inertia from a factored matrix
8524 
8525    Collective on Mat
8526 
8527    Input Parameter:
8528 .  mat - the matrix
8529 
8530    Output Parameters:
8531 +   nneg - number of negative eigenvalues
8532 .   nzero - number of zero eigenvalues
8533 -   npos - number of positive eigenvalues
8534 
8535    Level: advanced
8536 
8537    Notes:
8538     Matrix must have been factored by MatCholeskyFactor()
8539 
8540 
8541 @*/
8542 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8543 {
8544   PetscErrorCode ierr;
8545 
8546   PetscFunctionBegin;
8547   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8548   PetscValidType(mat,1);
8549   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8550   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8551   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8552   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8553   PetscFunctionReturn(0);
8554 }
8555 
8556 /* ----------------------------------------------------------------*/
8557 /*@C
8558    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8559 
8560    Neighbor-wise Collective on Mat and Vecs
8561 
8562    Input Parameters:
8563 +  mat - the factored matrix
8564 -  b - the right-hand-side vectors
8565 
8566    Output Parameter:
8567 .  x - the result vectors
8568 
8569    Notes:
8570    The vectors b and x cannot be the same.  I.e., one cannot
8571    call MatSolves(A,x,x).
8572 
8573    Notes:
8574    Most users should employ the simplified KSP interface for linear solvers
8575    instead of working directly with matrix algebra routines such as this.
8576    See, e.g., KSPCreate().
8577 
8578    Level: developer
8579 
8580    Concepts: matrices^triangular solves
8581 
8582 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8583 @*/
8584 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8585 {
8586   PetscErrorCode ierr;
8587 
8588   PetscFunctionBegin;
8589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8590   PetscValidType(mat,1);
8591   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8592   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8593   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8594 
8595   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8596   MatCheckPreallocated(mat,1);
8597   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8598   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8599   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8600   PetscFunctionReturn(0);
8601 }
8602 
8603 /*@
8604    MatIsSymmetric - Test whether a matrix is symmetric
8605 
8606    Collective on Mat
8607 
8608    Input Parameter:
8609 +  A - the matrix to test
8610 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8611 
8612    Output Parameters:
8613 .  flg - the result
8614 
8615    Notes:
8616     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8617 
8618    Level: intermediate
8619 
8620    Concepts: matrix^symmetry
8621 
8622 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8623 @*/
8624 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8625 {
8626   PetscErrorCode ierr;
8627 
8628   PetscFunctionBegin;
8629   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8630   PetscValidPointer(flg,2);
8631 
8632   if (!A->symmetric_set) {
8633     if (!A->ops->issymmetric) {
8634       MatType mattype;
8635       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8636       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8637     }
8638     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8639     if (!tol) {
8640       A->symmetric_set = PETSC_TRUE;
8641       A->symmetric     = *flg;
8642       if (A->symmetric) {
8643         A->structurally_symmetric_set = PETSC_TRUE;
8644         A->structurally_symmetric     = PETSC_TRUE;
8645       }
8646     }
8647   } else if (A->symmetric) {
8648     *flg = PETSC_TRUE;
8649   } else if (!tol) {
8650     *flg = PETSC_FALSE;
8651   } else {
8652     if (!A->ops->issymmetric) {
8653       MatType mattype;
8654       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8655       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8656     }
8657     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8658   }
8659   PetscFunctionReturn(0);
8660 }
8661 
8662 /*@
8663    MatIsHermitian - Test whether a matrix is Hermitian
8664 
8665    Collective on Mat
8666 
8667    Input Parameter:
8668 +  A - the matrix to test
8669 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8670 
8671    Output Parameters:
8672 .  flg - the result
8673 
8674    Level: intermediate
8675 
8676    Concepts: matrix^symmetry
8677 
8678 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8679           MatIsSymmetricKnown(), MatIsSymmetric()
8680 @*/
8681 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8682 {
8683   PetscErrorCode ierr;
8684 
8685   PetscFunctionBegin;
8686   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8687   PetscValidPointer(flg,2);
8688 
8689   if (!A->hermitian_set) {
8690     if (!A->ops->ishermitian) {
8691       MatType mattype;
8692       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8693       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8694     }
8695     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8696     if (!tol) {
8697       A->hermitian_set = PETSC_TRUE;
8698       A->hermitian     = *flg;
8699       if (A->hermitian) {
8700         A->structurally_symmetric_set = PETSC_TRUE;
8701         A->structurally_symmetric     = PETSC_TRUE;
8702       }
8703     }
8704   } else if (A->hermitian) {
8705     *flg = PETSC_TRUE;
8706   } else if (!tol) {
8707     *flg = PETSC_FALSE;
8708   } else {
8709     if (!A->ops->ishermitian) {
8710       MatType mattype;
8711       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8712       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8713     }
8714     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8715   }
8716   PetscFunctionReturn(0);
8717 }
8718 
8719 /*@
8720    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8721 
8722    Not Collective
8723 
8724    Input Parameter:
8725 .  A - the matrix to check
8726 
8727    Output Parameters:
8728 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8729 -  flg - the result
8730 
8731    Level: advanced
8732 
8733    Concepts: matrix^symmetry
8734 
8735    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8736          if you want it explicitly checked
8737 
8738 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8739 @*/
8740 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8741 {
8742   PetscFunctionBegin;
8743   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8744   PetscValidPointer(set,2);
8745   PetscValidPointer(flg,3);
8746   if (A->symmetric_set) {
8747     *set = PETSC_TRUE;
8748     *flg = A->symmetric;
8749   } else {
8750     *set = PETSC_FALSE;
8751   }
8752   PetscFunctionReturn(0);
8753 }
8754 
8755 /*@
8756    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8757 
8758    Not Collective
8759 
8760    Input Parameter:
8761 .  A - the matrix to check
8762 
8763    Output Parameters:
8764 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8765 -  flg - the result
8766 
8767    Level: advanced
8768 
8769    Concepts: matrix^symmetry
8770 
8771    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8772          if you want it explicitly checked
8773 
8774 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8775 @*/
8776 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8777 {
8778   PetscFunctionBegin;
8779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8780   PetscValidPointer(set,2);
8781   PetscValidPointer(flg,3);
8782   if (A->hermitian_set) {
8783     *set = PETSC_TRUE;
8784     *flg = A->hermitian;
8785   } else {
8786     *set = PETSC_FALSE;
8787   }
8788   PetscFunctionReturn(0);
8789 }
8790 
8791 /*@
8792    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8793 
8794    Collective on Mat
8795 
8796    Input Parameter:
8797 .  A - the matrix to test
8798 
8799    Output Parameters:
8800 .  flg - the result
8801 
8802    Level: intermediate
8803 
8804    Concepts: matrix^symmetry
8805 
8806 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8807 @*/
8808 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8809 {
8810   PetscErrorCode ierr;
8811 
8812   PetscFunctionBegin;
8813   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8814   PetscValidPointer(flg,2);
8815   if (!A->structurally_symmetric_set) {
8816     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8817     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8818 
8819     A->structurally_symmetric_set = PETSC_TRUE;
8820   }
8821   *flg = A->structurally_symmetric;
8822   PetscFunctionReturn(0);
8823 }
8824 
8825 /*@
8826    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8827        to be communicated to other processors during the MatAssemblyBegin/End() process
8828 
8829     Not collective
8830 
8831    Input Parameter:
8832 .   vec - the vector
8833 
8834    Output Parameters:
8835 +   nstash   - the size of the stash
8836 .   reallocs - the number of additional mallocs incurred.
8837 .   bnstash   - the size of the block stash
8838 -   breallocs - the number of additional mallocs incurred.in the block stash
8839 
8840    Level: advanced
8841 
8842 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8843 
8844 @*/
8845 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8846 {
8847   PetscErrorCode ierr;
8848 
8849   PetscFunctionBegin;
8850   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8851   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8852   PetscFunctionReturn(0);
8853 }
8854 
8855 /*@C
8856    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8857      parallel layout
8858 
8859    Collective on Mat
8860 
8861    Input Parameter:
8862 .  mat - the matrix
8863 
8864    Output Parameter:
8865 +   right - (optional) vector that the matrix can be multiplied against
8866 -   left - (optional) vector that the matrix vector product can be stored in
8867 
8868    Notes:
8869     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().
8870 
8871   Notes:
8872     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8873 
8874   Level: advanced
8875 
8876 .seealso: MatCreate(), VecDestroy()
8877 @*/
8878 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8879 {
8880   PetscErrorCode ierr;
8881 
8882   PetscFunctionBegin;
8883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8884   PetscValidType(mat,1);
8885   if (mat->ops->getvecs) {
8886     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8887   } else {
8888     PetscInt rbs,cbs;
8889     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8890     if (right) {
8891       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8892       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8893       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8894       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8895       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8896       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8897     }
8898     if (left) {
8899       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8900       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8901       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8902       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8903       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8904       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8905     }
8906   }
8907   PetscFunctionReturn(0);
8908 }
8909 
8910 /*@C
8911    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8912      with default values.
8913 
8914    Not Collective
8915 
8916    Input Parameters:
8917 .    info - the MatFactorInfo data structure
8918 
8919 
8920    Notes:
8921     The solvers are generally used through the KSP and PC objects, for example
8922           PCLU, PCILU, PCCHOLESKY, PCICC
8923 
8924    Level: developer
8925 
8926 .seealso: MatFactorInfo
8927 
8928     Developer Note: fortran interface is not autogenerated as the f90
8929     interface defintion cannot be generated correctly [due to MatFactorInfo]
8930 
8931 @*/
8932 
8933 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8934 {
8935   PetscErrorCode ierr;
8936 
8937   PetscFunctionBegin;
8938   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8939   PetscFunctionReturn(0);
8940 }
8941 
8942 /*@
8943    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8944 
8945    Collective on Mat
8946 
8947    Input Parameters:
8948 +  mat - the factored matrix
8949 -  is - the index set defining the Schur indices (0-based)
8950 
8951    Notes:
8952     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8953 
8954    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8955 
8956    Level: developer
8957 
8958    Concepts:
8959 
8960 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8961           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8962 
8963 @*/
8964 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8965 {
8966   PetscErrorCode ierr,(*f)(Mat,IS);
8967 
8968   PetscFunctionBegin;
8969   PetscValidType(mat,1);
8970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8971   PetscValidType(is,2);
8972   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8973   PetscCheckSameComm(mat,1,is,2);
8974   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8975   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8976   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");
8977   if (mat->schur) {
8978     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8979   }
8980   ierr = (*f)(mat,is);CHKERRQ(ierr);
8981   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8982   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8983   PetscFunctionReturn(0);
8984 }
8985 
8986 /*@
8987   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8988 
8989    Logically Collective on Mat
8990 
8991    Input Parameters:
8992 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8993 .  S - location where to return the Schur complement, can be NULL
8994 -  status - the status of the Schur complement matrix, can be NULL
8995 
8996    Notes:
8997    You must call MatFactorSetSchurIS() before calling this routine.
8998 
8999    The routine provides a copy of the Schur matrix stored within the solver data structures.
9000    The caller must destroy the object when it is no longer needed.
9001    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9002 
9003    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)
9004 
9005    Developer Notes:
9006     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9007    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9008 
9009    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9010 
9011    Level: advanced
9012 
9013    References:
9014 
9015 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9016 @*/
9017 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9018 {
9019   PetscErrorCode ierr;
9020 
9021   PetscFunctionBegin;
9022   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9023   if (S) PetscValidPointer(S,2);
9024   if (status) PetscValidPointer(status,3);
9025   if (S) {
9026     PetscErrorCode (*f)(Mat,Mat*);
9027 
9028     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9029     if (f) {
9030       ierr = (*f)(F,S);CHKERRQ(ierr);
9031     } else {
9032       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9033     }
9034   }
9035   if (status) *status = F->schur_status;
9036   PetscFunctionReturn(0);
9037 }
9038 
9039 /*@
9040   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9041 
9042    Logically Collective on Mat
9043 
9044    Input Parameters:
9045 +  F - the factored matrix obtained by calling MatGetFactor()
9046 .  *S - location where to return the Schur complement, can be NULL
9047 -  status - the status of the Schur complement matrix, can be NULL
9048 
9049    Notes:
9050    You must call MatFactorSetSchurIS() before calling this routine.
9051 
9052    Schur complement mode is currently implemented for sequential matrices.
9053    The routine returns a the Schur Complement stored within the data strutures of the solver.
9054    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9055    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9056 
9057    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9058 
9059    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9060 
9061    Level: advanced
9062 
9063    References:
9064 
9065 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9066 @*/
9067 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9068 {
9069   PetscFunctionBegin;
9070   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9071   if (S) PetscValidPointer(S,2);
9072   if (status) PetscValidPointer(status,3);
9073   if (S) *S = F->schur;
9074   if (status) *status = F->schur_status;
9075   PetscFunctionReturn(0);
9076 }
9077 
9078 /*@
9079   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9080 
9081    Logically Collective on Mat
9082 
9083    Input Parameters:
9084 +  F - the factored matrix obtained by calling MatGetFactor()
9085 .  *S - location where the Schur complement is stored
9086 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9087 
9088    Notes:
9089 
9090    Level: advanced
9091 
9092    References:
9093 
9094 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9095 @*/
9096 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9097 {
9098   PetscErrorCode ierr;
9099 
9100   PetscFunctionBegin;
9101   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9102   if (S) {
9103     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9104     *S = NULL;
9105   }
9106   F->schur_status = status;
9107   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9108   PetscFunctionReturn(0);
9109 }
9110 
9111 /*@
9112   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9113 
9114    Logically Collective on Mat
9115 
9116    Input Parameters:
9117 +  F - the factored matrix obtained by calling MatGetFactor()
9118 .  rhs - location where the right hand side of the Schur complement system is stored
9119 -  sol - location where the solution of the Schur complement system has to be returned
9120 
9121    Notes:
9122    The sizes of the vectors should match the size of the Schur complement
9123 
9124    Must be called after MatFactorSetSchurIS()
9125 
9126    Level: advanced
9127 
9128    References:
9129 
9130 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9131 @*/
9132 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9133 {
9134   PetscErrorCode ierr;
9135 
9136   PetscFunctionBegin;
9137   PetscValidType(F,1);
9138   PetscValidType(rhs,2);
9139   PetscValidType(sol,3);
9140   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9141   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9142   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9143   PetscCheckSameComm(F,1,rhs,2);
9144   PetscCheckSameComm(F,1,sol,3);
9145   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9146   switch (F->schur_status) {
9147   case MAT_FACTOR_SCHUR_FACTORED:
9148     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9149     break;
9150   case MAT_FACTOR_SCHUR_INVERTED:
9151     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9152     break;
9153   default:
9154     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9155     break;
9156   }
9157   PetscFunctionReturn(0);
9158 }
9159 
9160 /*@
9161   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9162 
9163    Logically Collective on Mat
9164 
9165    Input Parameters:
9166 +  F - the factored matrix obtained by calling MatGetFactor()
9167 .  rhs - location where the right hand side of the Schur complement system is stored
9168 -  sol - location where the solution of the Schur complement system has to be returned
9169 
9170    Notes:
9171    The sizes of the vectors should match the size of the Schur complement
9172 
9173    Must be called after MatFactorSetSchurIS()
9174 
9175    Level: advanced
9176 
9177    References:
9178 
9179 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9180 @*/
9181 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9182 {
9183   PetscErrorCode ierr;
9184 
9185   PetscFunctionBegin;
9186   PetscValidType(F,1);
9187   PetscValidType(rhs,2);
9188   PetscValidType(sol,3);
9189   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9190   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9191   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9192   PetscCheckSameComm(F,1,rhs,2);
9193   PetscCheckSameComm(F,1,sol,3);
9194   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9195   switch (F->schur_status) {
9196   case MAT_FACTOR_SCHUR_FACTORED:
9197     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9198     break;
9199   case MAT_FACTOR_SCHUR_INVERTED:
9200     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9201     break;
9202   default:
9203     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9204     break;
9205   }
9206   PetscFunctionReturn(0);
9207 }
9208 
9209 /*@
9210   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9211 
9212    Logically Collective on Mat
9213 
9214    Input Parameters:
9215 +  F - the factored matrix obtained by calling MatGetFactor()
9216 
9217    Notes:
9218     Must be called after MatFactorSetSchurIS().
9219 
9220    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9221 
9222    Level: advanced
9223 
9224    References:
9225 
9226 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9227 @*/
9228 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9229 {
9230   PetscErrorCode ierr;
9231 
9232   PetscFunctionBegin;
9233   PetscValidType(F,1);
9234   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9235   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9236   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9237   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9238   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9239   PetscFunctionReturn(0);
9240 }
9241 
9242 /*@
9243   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9244 
9245    Logically Collective on Mat
9246 
9247    Input Parameters:
9248 +  F - the factored matrix obtained by calling MatGetFactor()
9249 
9250    Notes:
9251     Must be called after MatFactorSetSchurIS().
9252 
9253    Level: advanced
9254 
9255    References:
9256 
9257 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9258 @*/
9259 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9260 {
9261   PetscErrorCode ierr;
9262 
9263   PetscFunctionBegin;
9264   PetscValidType(F,1);
9265   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9266   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9267   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9268   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9269   PetscFunctionReturn(0);
9270 }
9271 
9272 /*@
9273    MatPtAP - Creates the matrix product C = P^T * A * P
9274 
9275    Neighbor-wise Collective on Mat
9276 
9277    Input Parameters:
9278 +  A - the matrix
9279 .  P - the projection matrix
9280 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9281 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9282           if the result is a dense matrix this is irrelevent
9283 
9284    Output Parameters:
9285 .  C - the product matrix
9286 
9287    Notes:
9288    C will be created and must be destroyed by the user with MatDestroy().
9289 
9290    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9291    which inherit from AIJ.
9292 
9293    Level: intermediate
9294 
9295 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9296 @*/
9297 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9298 {
9299   PetscErrorCode ierr;
9300   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9301   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9302   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9303   PetscBool      sametype;
9304 
9305   PetscFunctionBegin;
9306   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9307   PetscValidType(A,1);
9308   MatCheckPreallocated(A,1);
9309   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9310   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9311   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9312   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9313   PetscValidType(P,2);
9314   MatCheckPreallocated(P,2);
9315   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9316   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9317 
9318   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);
9319   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);
9320   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9321   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9322 
9323   if (scall == MAT_REUSE_MATRIX) {
9324     PetscValidPointer(*C,5);
9325     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9326 
9327     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9328     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9329     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9330     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9331     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9332     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9333     PetscFunctionReturn(0);
9334   }
9335 
9336   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9337   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9338 
9339   fA = A->ops->ptap;
9340   fP = P->ops->ptap;
9341   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9342   if (fP == fA && sametype) {
9343     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9344     ptap = fA;
9345   } else {
9346     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9347     char ptapname[256];
9348     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9349     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9350     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9351     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9352     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9353     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9354     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);
9355   }
9356 
9357   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9358   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9359   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9360   if (A->symmetric_set && A->symmetric) {
9361     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9362   }
9363   PetscFunctionReturn(0);
9364 }
9365 
9366 /*@
9367    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9368 
9369    Neighbor-wise Collective on Mat
9370 
9371    Input Parameters:
9372 +  A - the matrix
9373 -  P - the projection matrix
9374 
9375    Output Parameters:
9376 .  C - the product matrix
9377 
9378    Notes:
9379    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9380    the user using MatDeatroy().
9381 
9382    This routine is currently only implemented for pairs of AIJ matrices and classes
9383    which inherit from AIJ.  C will be of type MATAIJ.
9384 
9385    Level: intermediate
9386 
9387 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9388 @*/
9389 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9390 {
9391   PetscErrorCode ierr;
9392 
9393   PetscFunctionBegin;
9394   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9395   PetscValidType(A,1);
9396   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9397   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9398   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9399   PetscValidType(P,2);
9400   MatCheckPreallocated(P,2);
9401   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9402   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9403   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9404   PetscValidType(C,3);
9405   MatCheckPreallocated(C,3);
9406   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9407   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);
9408   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);
9409   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);
9410   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);
9411   MatCheckPreallocated(A,1);
9412 
9413   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9414   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9415   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9416   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9417   PetscFunctionReturn(0);
9418 }
9419 
9420 /*@
9421    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9422 
9423    Neighbor-wise Collective on Mat
9424 
9425    Input Parameters:
9426 +  A - the matrix
9427 -  P - the projection matrix
9428 
9429    Output Parameters:
9430 .  C - the (i,j) structure of the product matrix
9431 
9432    Notes:
9433    C will be created and must be destroyed by the user with MatDestroy().
9434 
9435    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9436    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9437    this (i,j) structure by calling MatPtAPNumeric().
9438 
9439    Level: intermediate
9440 
9441 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9442 @*/
9443 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9444 {
9445   PetscErrorCode ierr;
9446 
9447   PetscFunctionBegin;
9448   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9449   PetscValidType(A,1);
9450   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9451   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9452   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9453   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9454   PetscValidType(P,2);
9455   MatCheckPreallocated(P,2);
9456   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9457   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9458   PetscValidPointer(C,3);
9459 
9460   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);
9461   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9462   MatCheckPreallocated(A,1);
9463 
9464   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9465   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9466   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9467   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9468 
9469   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9470   PetscFunctionReturn(0);
9471 }
9472 
9473 /*@
9474    MatRARt - Creates the matrix product C = R * A * R^T
9475 
9476    Neighbor-wise Collective on Mat
9477 
9478    Input Parameters:
9479 +  A - the matrix
9480 .  R - the projection matrix
9481 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9482 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9483           if the result is a dense matrix this is irrelevent
9484 
9485    Output Parameters:
9486 .  C - the product matrix
9487 
9488    Notes:
9489    C will be created and must be destroyed by the user with MatDestroy().
9490 
9491    This routine is currently only implemented for pairs of AIJ matrices and classes
9492    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9493    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9494    We recommend using MatPtAP().
9495 
9496    Level: intermediate
9497 
9498 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9499 @*/
9500 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9501 {
9502   PetscErrorCode ierr;
9503 
9504   PetscFunctionBegin;
9505   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9506   PetscValidType(A,1);
9507   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9508   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9509   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9510   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9511   PetscValidType(R,2);
9512   MatCheckPreallocated(R,2);
9513   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9514   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9515   PetscValidPointer(C,3);
9516   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);
9517 
9518   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9519   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9520   MatCheckPreallocated(A,1);
9521 
9522   if (!A->ops->rart) {
9523     Mat Rt;
9524     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9525     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9526     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9527     PetscFunctionReturn(0);
9528   }
9529   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9530   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9531   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9532   PetscFunctionReturn(0);
9533 }
9534 
9535 /*@
9536    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9537 
9538    Neighbor-wise Collective on Mat
9539 
9540    Input Parameters:
9541 +  A - the matrix
9542 -  R - the projection matrix
9543 
9544    Output Parameters:
9545 .  C - the product matrix
9546 
9547    Notes:
9548    C must have been created by calling MatRARtSymbolic and must be destroyed by
9549    the user using MatDestroy().
9550 
9551    This routine is currently only implemented for pairs of AIJ matrices and classes
9552    which inherit from AIJ.  C will be of type MATAIJ.
9553 
9554    Level: intermediate
9555 
9556 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9557 @*/
9558 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9559 {
9560   PetscErrorCode ierr;
9561 
9562   PetscFunctionBegin;
9563   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9564   PetscValidType(A,1);
9565   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9566   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9567   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9568   PetscValidType(R,2);
9569   MatCheckPreallocated(R,2);
9570   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9571   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9572   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9573   PetscValidType(C,3);
9574   MatCheckPreallocated(C,3);
9575   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9576   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);
9577   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);
9578   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);
9579   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);
9580   MatCheckPreallocated(A,1);
9581 
9582   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9583   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9584   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9585   PetscFunctionReturn(0);
9586 }
9587 
9588 /*@
9589    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9590 
9591    Neighbor-wise Collective on Mat
9592 
9593    Input Parameters:
9594 +  A - the matrix
9595 -  R - the projection matrix
9596 
9597    Output Parameters:
9598 .  C - the (i,j) structure of the product matrix
9599 
9600    Notes:
9601    C will be created and must be destroyed by the user with MatDestroy().
9602 
9603    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9604    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9605    this (i,j) structure by calling MatRARtNumeric().
9606 
9607    Level: intermediate
9608 
9609 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9610 @*/
9611 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9612 {
9613   PetscErrorCode ierr;
9614 
9615   PetscFunctionBegin;
9616   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9617   PetscValidType(A,1);
9618   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9619   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9620   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9621   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9622   PetscValidType(R,2);
9623   MatCheckPreallocated(R,2);
9624   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9625   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9626   PetscValidPointer(C,3);
9627 
9628   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);
9629   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);
9630   MatCheckPreallocated(A,1);
9631   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9632   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9633   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9634 
9635   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9636   PetscFunctionReturn(0);
9637 }
9638 
9639 /*@
9640    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9641 
9642    Neighbor-wise Collective on Mat
9643 
9644    Input Parameters:
9645 +  A - the left matrix
9646 .  B - the right matrix
9647 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9648 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9649           if the result is a dense matrix this is irrelevent
9650 
9651    Output Parameters:
9652 .  C - the product matrix
9653 
9654    Notes:
9655    Unless scall is MAT_REUSE_MATRIX C will be created.
9656 
9657    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
9658    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9659 
9660    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9661    actually needed.
9662 
9663    If you have many matrices with the same non-zero structure to multiply, you
9664    should either
9665 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9666 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9667    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
9668    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9669 
9670    Level: intermediate
9671 
9672 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9673 @*/
9674 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9675 {
9676   PetscErrorCode ierr;
9677   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9678   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9679   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9680 
9681   PetscFunctionBegin;
9682   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9683   PetscValidType(A,1);
9684   MatCheckPreallocated(A,1);
9685   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9686   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9687   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9688   PetscValidType(B,2);
9689   MatCheckPreallocated(B,2);
9690   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9691   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9692   PetscValidPointer(C,3);
9693   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9694   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);
9695   if (scall == MAT_REUSE_MATRIX) {
9696     PetscValidPointer(*C,5);
9697     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9698     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9699     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9700     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9701     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9702     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9703     PetscFunctionReturn(0);
9704   }
9705   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9706   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9707 
9708   fA = A->ops->matmult;
9709   fB = B->ops->matmult;
9710   if (fB == fA) {
9711     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9712     mult = fB;
9713   } else {
9714     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9715     char multname[256];
9716     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9717     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9718     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9719     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9720     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9721     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9722     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);
9723   }
9724   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9725   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9726   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9727   PetscFunctionReturn(0);
9728 }
9729 
9730 /*@
9731    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9732    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9733 
9734    Neighbor-wise Collective on Mat
9735 
9736    Input Parameters:
9737 +  A - the left matrix
9738 .  B - the right matrix
9739 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9740       if C is a dense matrix this is irrelevent
9741 
9742    Output Parameters:
9743 .  C - the product matrix
9744 
9745    Notes:
9746    Unless scall is MAT_REUSE_MATRIX C will be created.
9747 
9748    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9749    actually needed.
9750 
9751    This routine is currently implemented for
9752     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9753     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9754     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9755 
9756    Level: intermediate
9757 
9758    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9759      We should incorporate them into PETSc.
9760 
9761 .seealso: MatMatMult(), MatMatMultNumeric()
9762 @*/
9763 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9764 {
9765   PetscErrorCode ierr;
9766   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9767   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9768   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9769 
9770   PetscFunctionBegin;
9771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9772   PetscValidType(A,1);
9773   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9774   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9775 
9776   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9777   PetscValidType(B,2);
9778   MatCheckPreallocated(B,2);
9779   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9780   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9781   PetscValidPointer(C,3);
9782 
9783   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);
9784   if (fill == PETSC_DEFAULT) fill = 2.0;
9785   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9786   MatCheckPreallocated(A,1);
9787 
9788   Asymbolic = A->ops->matmultsymbolic;
9789   Bsymbolic = B->ops->matmultsymbolic;
9790   if (Asymbolic == Bsymbolic) {
9791     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9792     symbolic = Bsymbolic;
9793   } else { /* dispatch based on the type of A and B */
9794     char symbolicname[256];
9795     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9796     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9797     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9798     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9799     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9800     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9801     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);
9802   }
9803   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9804   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9805   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9806   PetscFunctionReturn(0);
9807 }
9808 
9809 /*@
9810    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9811    Call this routine after first calling MatMatMultSymbolic().
9812 
9813    Neighbor-wise Collective on Mat
9814 
9815    Input Parameters:
9816 +  A - the left matrix
9817 -  B - the right matrix
9818 
9819    Output Parameters:
9820 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9821 
9822    Notes:
9823    C must have been created with MatMatMultSymbolic().
9824 
9825    This routine is currently implemented for
9826     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9827     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9828     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9829 
9830    Level: intermediate
9831 
9832 .seealso: MatMatMult(), MatMatMultSymbolic()
9833 @*/
9834 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9835 {
9836   PetscErrorCode ierr;
9837 
9838   PetscFunctionBegin;
9839   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9840   PetscFunctionReturn(0);
9841 }
9842 
9843 /*@
9844    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9845 
9846    Neighbor-wise Collective on Mat
9847 
9848    Input Parameters:
9849 +  A - the left matrix
9850 .  B - the right matrix
9851 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9852 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9853 
9854    Output Parameters:
9855 .  C - the product matrix
9856 
9857    Notes:
9858    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9859 
9860    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9861 
9862   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9863    actually needed.
9864 
9865    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9866 
9867    Level: intermediate
9868 
9869 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9870 @*/
9871 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9872 {
9873   PetscErrorCode ierr;
9874   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9875   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9876 
9877   PetscFunctionBegin;
9878   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9879   PetscValidType(A,1);
9880   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9881   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9882   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9883   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9884   PetscValidType(B,2);
9885   MatCheckPreallocated(B,2);
9886   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9887   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9888   PetscValidPointer(C,3);
9889   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);
9890   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9891   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9892   MatCheckPreallocated(A,1);
9893 
9894   fA = A->ops->mattransposemult;
9895   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9896   fB = B->ops->mattransposemult;
9897   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9898   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);
9899 
9900   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9901   if (scall == MAT_INITIAL_MATRIX) {
9902     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9903     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9904     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9905   }
9906   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9907   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9908   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9909   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9910   PetscFunctionReturn(0);
9911 }
9912 
9913 /*@
9914    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9915 
9916    Neighbor-wise Collective on Mat
9917 
9918    Input Parameters:
9919 +  A - the left matrix
9920 .  B - the right matrix
9921 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9922 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9923 
9924    Output Parameters:
9925 .  C - the product matrix
9926 
9927    Notes:
9928    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9929 
9930    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9931 
9932   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9933    actually needed.
9934 
9935    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9936    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9937 
9938    Level: intermediate
9939 
9940 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9941 @*/
9942 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9943 {
9944   PetscErrorCode ierr;
9945   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9946   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9947   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9948 
9949   PetscFunctionBegin;
9950   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9951   PetscValidType(A,1);
9952   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9953   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9954   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9955   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9956   PetscValidType(B,2);
9957   MatCheckPreallocated(B,2);
9958   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9959   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9960   PetscValidPointer(C,3);
9961   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);
9962   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9963   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9964   MatCheckPreallocated(A,1);
9965 
9966   fA = A->ops->transposematmult;
9967   fB = B->ops->transposematmult;
9968   if (fB==fA) {
9969     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9970     transposematmult = fA;
9971   } else {
9972     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9973     char multname[256];
9974     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9975     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9976     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9977     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9978     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9979     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9980     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);
9981   }
9982   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9983   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9984   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9985   PetscFunctionReturn(0);
9986 }
9987 
9988 /*@
9989    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9990 
9991    Neighbor-wise Collective on Mat
9992 
9993    Input Parameters:
9994 +  A - the left matrix
9995 .  B - the middle matrix
9996 .  C - the right matrix
9997 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9998 -  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
9999           if the result is a dense matrix this is irrelevent
10000 
10001    Output Parameters:
10002 .  D - the product matrix
10003 
10004    Notes:
10005    Unless scall is MAT_REUSE_MATRIX D will be created.
10006 
10007    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10008 
10009    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10010    actually needed.
10011 
10012    If you have many matrices with the same non-zero structure to multiply, you
10013    should use MAT_REUSE_MATRIX in all calls but the first or
10014 
10015    Level: intermediate
10016 
10017 .seealso: MatMatMult, MatPtAP()
10018 @*/
10019 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10020 {
10021   PetscErrorCode ierr;
10022   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10023   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10024   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10025   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10026 
10027   PetscFunctionBegin;
10028   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10029   PetscValidType(A,1);
10030   MatCheckPreallocated(A,1);
10031   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10032   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10033   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10034   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10035   PetscValidType(B,2);
10036   MatCheckPreallocated(B,2);
10037   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10038   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10039   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10040   PetscValidPointer(C,3);
10041   MatCheckPreallocated(C,3);
10042   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10043   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10044   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);
10045   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);
10046   if (scall == MAT_REUSE_MATRIX) {
10047     PetscValidPointer(*D,6);
10048     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10049     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10050     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10051     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10052     PetscFunctionReturn(0);
10053   }
10054   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10055   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10056 
10057   fA = A->ops->matmatmult;
10058   fB = B->ops->matmatmult;
10059   fC = C->ops->matmatmult;
10060   if (fA == fB && fA == fC) {
10061     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10062     mult = fA;
10063   } else {
10064     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10065     char multname[256];
10066     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10067     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10068     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10069     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10070     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10071     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10072     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10073     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10074     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);
10075   }
10076   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10077   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10078   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10079   PetscFunctionReturn(0);
10080 }
10081 
10082 /*@
10083    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10084 
10085    Collective on Mat
10086 
10087    Input Parameters:
10088 +  mat - the matrix
10089 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10090 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10091 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10092 
10093    Output Parameter:
10094 .  matredundant - redundant matrix
10095 
10096    Notes:
10097    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10098    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10099 
10100    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10101    calling it.
10102 
10103    Level: advanced
10104 
10105    Concepts: subcommunicator
10106    Concepts: duplicate matrix
10107 
10108 .seealso: MatDestroy()
10109 @*/
10110 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10111 {
10112   PetscErrorCode ierr;
10113   MPI_Comm       comm;
10114   PetscMPIInt    size;
10115   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10116   Mat_Redundant  *redund=NULL;
10117   PetscSubcomm   psubcomm=NULL;
10118   MPI_Comm       subcomm_in=subcomm;
10119   Mat            *matseq;
10120   IS             isrow,iscol;
10121   PetscBool      newsubcomm=PETSC_FALSE;
10122 
10123   PetscFunctionBegin;
10124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10125   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10126     PetscValidPointer(*matredundant,5);
10127     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10128   }
10129 
10130   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10131   if (size == 1 || nsubcomm == 1) {
10132     if (reuse == MAT_INITIAL_MATRIX) {
10133       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10134     } else {
10135       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");
10136       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10137     }
10138     PetscFunctionReturn(0);
10139   }
10140 
10141   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10142   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10143   MatCheckPreallocated(mat,1);
10144 
10145   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10146   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10147     /* create psubcomm, then get subcomm */
10148     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10149     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10150     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10151 
10152     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10153     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10154     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10155     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10156     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10157     newsubcomm = PETSC_TRUE;
10158     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10159   }
10160 
10161   /* get isrow, iscol and a local sequential matrix matseq[0] */
10162   if (reuse == MAT_INITIAL_MATRIX) {
10163     mloc_sub = PETSC_DECIDE;
10164     nloc_sub = PETSC_DECIDE;
10165     if (bs < 1) {
10166       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10167       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10168     } else {
10169       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10170       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10171     }
10172     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10173     rstart = rend - mloc_sub;
10174     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10175     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10176   } else { /* reuse == MAT_REUSE_MATRIX */
10177     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");
10178     /* retrieve subcomm */
10179     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10180     redund = (*matredundant)->redundant;
10181     isrow  = redund->isrow;
10182     iscol  = redund->iscol;
10183     matseq = redund->matseq;
10184   }
10185   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10186 
10187   /* get matredundant over subcomm */
10188   if (reuse == MAT_INITIAL_MATRIX) {
10189     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10190 
10191     /* create a supporting struct and attach it to C for reuse */
10192     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10193     (*matredundant)->redundant = redund;
10194     redund->isrow              = isrow;
10195     redund->iscol              = iscol;
10196     redund->matseq             = matseq;
10197     if (newsubcomm) {
10198       redund->subcomm          = subcomm;
10199     } else {
10200       redund->subcomm          = MPI_COMM_NULL;
10201     }
10202   } else {
10203     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10204   }
10205   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10206   PetscFunctionReturn(0);
10207 }
10208 
10209 /*@C
10210    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10211    a given 'mat' object. Each submatrix can span multiple procs.
10212 
10213    Collective on Mat
10214 
10215    Input Parameters:
10216 +  mat - the matrix
10217 .  subcomm - the subcommunicator obtained by com_split(comm)
10218 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10219 
10220    Output Parameter:
10221 .  subMat - 'parallel submatrices each spans a given subcomm
10222 
10223   Notes:
10224   The submatrix partition across processors is dictated by 'subComm' a
10225   communicator obtained by com_split(comm). The comm_split
10226   is not restriced to be grouped with consecutive original ranks.
10227 
10228   Due the comm_split() usage, the parallel layout of the submatrices
10229   map directly to the layout of the original matrix [wrt the local
10230   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10231   into the 'DiagonalMat' of the subMat, hence it is used directly from
10232   the subMat. However the offDiagMat looses some columns - and this is
10233   reconstructed with MatSetValues()
10234 
10235   Level: advanced
10236 
10237   Concepts: subcommunicator
10238   Concepts: submatrices
10239 
10240 .seealso: MatCreateSubMatrices()
10241 @*/
10242 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10243 {
10244   PetscErrorCode ierr;
10245   PetscMPIInt    commsize,subCommSize;
10246 
10247   PetscFunctionBegin;
10248   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10249   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10250   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10251 
10252   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");
10253   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10254   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10255   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10256   PetscFunctionReturn(0);
10257 }
10258 
10259 /*@
10260    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10261 
10262    Not Collective
10263 
10264    Input Arguments:
10265    mat - matrix to extract local submatrix from
10266    isrow - local row indices for submatrix
10267    iscol - local column indices for submatrix
10268 
10269    Output Arguments:
10270    submat - the submatrix
10271 
10272    Level: intermediate
10273 
10274    Notes:
10275    The submat should be returned with MatRestoreLocalSubMatrix().
10276 
10277    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10278    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10279 
10280    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10281    MatSetValuesBlockedLocal() will also be implemented.
10282 
10283    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10284    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10285 
10286 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10287 @*/
10288 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10289 {
10290   PetscErrorCode ierr;
10291 
10292   PetscFunctionBegin;
10293   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10294   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10295   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10296   PetscCheckSameComm(isrow,2,iscol,3);
10297   PetscValidPointer(submat,4);
10298   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10299 
10300   if (mat->ops->getlocalsubmatrix) {
10301     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10302   } else {
10303     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10304   }
10305   PetscFunctionReturn(0);
10306 }
10307 
10308 /*@
10309    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10310 
10311    Not Collective
10312 
10313    Input Arguments:
10314    mat - matrix to extract local submatrix from
10315    isrow - local row indices for submatrix
10316    iscol - local column indices for submatrix
10317    submat - the submatrix
10318 
10319    Level: intermediate
10320 
10321 .seealso: MatGetLocalSubMatrix()
10322 @*/
10323 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10324 {
10325   PetscErrorCode ierr;
10326 
10327   PetscFunctionBegin;
10328   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10329   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10330   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10331   PetscCheckSameComm(isrow,2,iscol,3);
10332   PetscValidPointer(submat,4);
10333   if (*submat) {
10334     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10335   }
10336 
10337   if (mat->ops->restorelocalsubmatrix) {
10338     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10339   } else {
10340     ierr = MatDestroy(submat);CHKERRQ(ierr);
10341   }
10342   *submat = NULL;
10343   PetscFunctionReturn(0);
10344 }
10345 
10346 /* --------------------------------------------------------*/
10347 /*@
10348    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10349 
10350    Collective on Mat
10351 
10352    Input Parameter:
10353 .  mat - the matrix
10354 
10355    Output Parameter:
10356 .  is - if any rows have zero diagonals this contains the list of them
10357 
10358    Level: developer
10359 
10360    Concepts: matrix-vector product
10361 
10362 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10363 @*/
10364 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10365 {
10366   PetscErrorCode ierr;
10367 
10368   PetscFunctionBegin;
10369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10370   PetscValidType(mat,1);
10371   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10372   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10373 
10374   if (!mat->ops->findzerodiagonals) {
10375     Vec                diag;
10376     const PetscScalar *a;
10377     PetscInt          *rows;
10378     PetscInt           rStart, rEnd, r, nrow = 0;
10379 
10380     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10381     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10382     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10383     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10384     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10385     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10386     nrow = 0;
10387     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10388     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10389     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10390     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10391   } else {
10392     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10393   }
10394   PetscFunctionReturn(0);
10395 }
10396 
10397 /*@
10398    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10399 
10400    Collective on Mat
10401 
10402    Input Parameter:
10403 .  mat - the matrix
10404 
10405    Output Parameter:
10406 .  is - contains the list of rows with off block diagonal entries
10407 
10408    Level: developer
10409 
10410    Concepts: matrix-vector product
10411 
10412 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10413 @*/
10414 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10415 {
10416   PetscErrorCode ierr;
10417 
10418   PetscFunctionBegin;
10419   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10420   PetscValidType(mat,1);
10421   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10422   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10423 
10424   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10425   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10426   PetscFunctionReturn(0);
10427 }
10428 
10429 /*@C
10430   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10431 
10432   Collective on Mat
10433 
10434   Input Parameters:
10435 . mat - the matrix
10436 
10437   Output Parameters:
10438 . values - the block inverses in column major order (FORTRAN-like)
10439 
10440    Note:
10441    This routine is not available from Fortran.
10442 
10443   Level: advanced
10444 
10445 .seealso: MatInvertBockDiagonalMat
10446 @*/
10447 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10448 {
10449   PetscErrorCode ierr;
10450 
10451   PetscFunctionBegin;
10452   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10453   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10454   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10455   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10456   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10457   PetscFunctionReturn(0);
10458 }
10459 
10460 /*@C
10461   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10462 
10463   Collective on Mat
10464 
10465   Input Parameters:
10466 + mat - the matrix
10467 . nblocks - the number of blocks
10468 - bsizes - the size of each block
10469 
10470   Output Parameters:
10471 . values - the block inverses in column major order (FORTRAN-like)
10472 
10473    Note:
10474    This routine is not available from Fortran.
10475 
10476   Level: advanced
10477 
10478 .seealso: MatInvertBockDiagonal()
10479 @*/
10480 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10481 {
10482   PetscErrorCode ierr;
10483 
10484   PetscFunctionBegin;
10485   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10486   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10487   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10488   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10489   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10490   PetscFunctionReturn(0);
10491 }
10492 
10493 /*@
10494   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10495 
10496   Collective on Mat
10497 
10498   Input Parameters:
10499 . A - the matrix
10500 
10501   Output Parameters:
10502 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10503 
10504   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10505 
10506   Level: advanced
10507 
10508 .seealso: MatInvertBockDiagonal()
10509 @*/
10510 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10511 {
10512   PetscErrorCode     ierr;
10513   const PetscScalar *vals;
10514   PetscInt          *dnnz;
10515   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10516 
10517   PetscFunctionBegin;
10518   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10519   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10520   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10521   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10522   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10523   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10524   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10525   for(j = 0; j < m/bs; j++) {
10526     dnnz[j] = 1;
10527   }
10528   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10529   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10530   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10531   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10532   for (i = rstart/bs; i < rend/bs; i++) {
10533     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10534   }
10535   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10536   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10537   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10538   PetscFunctionReturn(0);
10539 }
10540 
10541 /*@C
10542     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10543     via MatTransposeColoringCreate().
10544 
10545     Collective on MatTransposeColoring
10546 
10547     Input Parameter:
10548 .   c - coloring context
10549 
10550     Level: intermediate
10551 
10552 .seealso: MatTransposeColoringCreate()
10553 @*/
10554 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10555 {
10556   PetscErrorCode       ierr;
10557   MatTransposeColoring matcolor=*c;
10558 
10559   PetscFunctionBegin;
10560   if (!matcolor) PetscFunctionReturn(0);
10561   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10562 
10563   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10564   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10565   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10566   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10567   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10568   if (matcolor->brows>0) {
10569     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10570   }
10571   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10572   PetscFunctionReturn(0);
10573 }
10574 
10575 /*@C
10576     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10577     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10578     MatTransposeColoring to sparse B.
10579 
10580     Collective on MatTransposeColoring
10581 
10582     Input Parameters:
10583 +   B - sparse matrix B
10584 .   Btdense - symbolic dense matrix B^T
10585 -   coloring - coloring context created with MatTransposeColoringCreate()
10586 
10587     Output Parameter:
10588 .   Btdense - dense matrix B^T
10589 
10590     Level: advanced
10591 
10592      Notes:
10593     These are used internally for some implementations of MatRARt()
10594 
10595 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10596 
10597 .keywords: coloring
10598 @*/
10599 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10600 {
10601   PetscErrorCode ierr;
10602 
10603   PetscFunctionBegin;
10604   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10605   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10606   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10607 
10608   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10609   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10610   PetscFunctionReturn(0);
10611 }
10612 
10613 /*@C
10614     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10615     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10616     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10617     Csp from Cden.
10618 
10619     Collective on MatTransposeColoring
10620 
10621     Input Parameters:
10622 +   coloring - coloring context created with MatTransposeColoringCreate()
10623 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10624 
10625     Output Parameter:
10626 .   Csp - sparse matrix
10627 
10628     Level: advanced
10629 
10630      Notes:
10631     These are used internally for some implementations of MatRARt()
10632 
10633 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10634 
10635 .keywords: coloring
10636 @*/
10637 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10638 {
10639   PetscErrorCode ierr;
10640 
10641   PetscFunctionBegin;
10642   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10643   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10644   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10645 
10646   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10647   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10648   PetscFunctionReturn(0);
10649 }
10650 
10651 /*@C
10652    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10653 
10654    Collective on Mat
10655 
10656    Input Parameters:
10657 +  mat - the matrix product C
10658 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10659 
10660     Output Parameter:
10661 .   color - the new coloring context
10662 
10663     Level: intermediate
10664 
10665 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10666            MatTransColoringApplyDenToSp()
10667 @*/
10668 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10669 {
10670   MatTransposeColoring c;
10671   MPI_Comm             comm;
10672   PetscErrorCode       ierr;
10673 
10674   PetscFunctionBegin;
10675   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10676   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10677   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10678 
10679   c->ctype = iscoloring->ctype;
10680   if (mat->ops->transposecoloringcreate) {
10681     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10682   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10683 
10684   *color = c;
10685   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10686   PetscFunctionReturn(0);
10687 }
10688 
10689 /*@
10690       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10691         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10692         same, otherwise it will be larger
10693 
10694      Not Collective
10695 
10696   Input Parameter:
10697 .    A  - the matrix
10698 
10699   Output Parameter:
10700 .    state - the current state
10701 
10702   Notes:
10703     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10704          different matrices
10705 
10706   Level: intermediate
10707 
10708 @*/
10709 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10710 {
10711   PetscFunctionBegin;
10712   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10713   *state = mat->nonzerostate;
10714   PetscFunctionReturn(0);
10715 }
10716 
10717 /*@
10718       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10719                  matrices from each processor
10720 
10721     Collective on MPI_Comm
10722 
10723    Input Parameters:
10724 +    comm - the communicators the parallel matrix will live on
10725 .    seqmat - the input sequential matrices
10726 .    n - number of local columns (or PETSC_DECIDE)
10727 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10728 
10729    Output Parameter:
10730 .    mpimat - the parallel matrix generated
10731 
10732     Level: advanced
10733 
10734    Notes:
10735     The number of columns of the matrix in EACH processor MUST be the same.
10736 
10737 @*/
10738 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10739 {
10740   PetscErrorCode ierr;
10741 
10742   PetscFunctionBegin;
10743   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10744   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");
10745 
10746   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10747   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10748   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10749   PetscFunctionReturn(0);
10750 }
10751 
10752 /*@
10753      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10754                  ranks' ownership ranges.
10755 
10756     Collective on A
10757 
10758    Input Parameters:
10759 +    A   - the matrix to create subdomains from
10760 -    N   - requested number of subdomains
10761 
10762 
10763    Output Parameters:
10764 +    n   - number of subdomains resulting on this rank
10765 -    iss - IS list with indices of subdomains on this rank
10766 
10767     Level: advanced
10768 
10769     Notes:
10770     number of subdomains must be smaller than the communicator size
10771 @*/
10772 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10773 {
10774   MPI_Comm        comm,subcomm;
10775   PetscMPIInt     size,rank,color;
10776   PetscInt        rstart,rend,k;
10777   PetscErrorCode  ierr;
10778 
10779   PetscFunctionBegin;
10780   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10781   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10782   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10783   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);
10784   *n = 1;
10785   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10786   color = rank/k;
10787   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10788   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10789   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10790   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10791   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10792   PetscFunctionReturn(0);
10793 }
10794 
10795 /*@
10796    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10797 
10798    If the interpolation and restriction operators are the same, uses MatPtAP.
10799    If they are not the same, use MatMatMatMult.
10800 
10801    Once the coarse grid problem is constructed, correct for interpolation operators
10802    that are not of full rank, which can legitimately happen in the case of non-nested
10803    geometric multigrid.
10804 
10805    Input Parameters:
10806 +  restrct - restriction operator
10807 .  dA - fine grid matrix
10808 .  interpolate - interpolation operator
10809 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10810 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10811 
10812    Output Parameters:
10813 .  A - the Galerkin coarse matrix
10814 
10815    Options Database Key:
10816 .  -pc_mg_galerkin <both,pmat,mat,none>
10817 
10818    Level: developer
10819 
10820 .keywords: MG, multigrid, Galerkin
10821 
10822 .seealso: MatPtAP(), MatMatMatMult()
10823 @*/
10824 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10825 {
10826   PetscErrorCode ierr;
10827   IS             zerorows;
10828   Vec            diag;
10829 
10830   PetscFunctionBegin;
10831   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10832   /* Construct the coarse grid matrix */
10833   if (interpolate == restrct) {
10834     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10835   } else {
10836     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10837   }
10838 
10839   /* If the interpolation matrix is not of full rank, A will have zero rows.
10840      This can legitimately happen in the case of non-nested geometric multigrid.
10841      In that event, we set the rows of the matrix to the rows of the identity,
10842      ignoring the equations (as the RHS will also be zero). */
10843 
10844   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10845 
10846   if (zerorows != NULL) { /* if there are any zero rows */
10847     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10848     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10849     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10850     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10851     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10852     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10853   }
10854   PetscFunctionReturn(0);
10855 }
10856 
10857 /*@C
10858     MatSetOperation - Allows user to set a matrix operation for any matrix type
10859 
10860    Logically Collective on Mat
10861 
10862     Input Parameters:
10863 +   mat - the matrix
10864 .   op - the name of the operation
10865 -   f - the function that provides the operation
10866 
10867    Level: developer
10868 
10869     Usage:
10870 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10871 $      ierr = MatCreateXXX(comm,...&A);
10872 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10873 
10874     Notes:
10875     See the file include/petscmat.h for a complete list of matrix
10876     operations, which all have the form MATOP_<OPERATION>, where
10877     <OPERATION> is the name (in all capital letters) of the
10878     user interface routine (e.g., MatMult() -> MATOP_MULT).
10879 
10880     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10881     sequence as the usual matrix interface routines, since they
10882     are intended to be accessed via the usual matrix interface
10883     routines, e.g.,
10884 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10885 
10886     In particular each function MUST return an error code of 0 on success and
10887     nonzero on failure.
10888 
10889     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10890 
10891 .keywords: matrix, set, operation
10892 
10893 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10894 @*/
10895 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10896 {
10897   PetscFunctionBegin;
10898   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10899   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10900     mat->ops->viewnative = mat->ops->view;
10901   }
10902   (((void(**)(void))mat->ops)[op]) = f;
10903   PetscFunctionReturn(0);
10904 }
10905 
10906 /*@C
10907     MatGetOperation - Gets a matrix operation for any matrix type.
10908 
10909     Not Collective
10910 
10911     Input Parameters:
10912 +   mat - the matrix
10913 -   op - the name of the operation
10914 
10915     Output Parameter:
10916 .   f - the function that provides the operation
10917 
10918     Level: developer
10919 
10920     Usage:
10921 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10922 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10923 
10924     Notes:
10925     See the file include/petscmat.h for a complete list of matrix
10926     operations, which all have the form MATOP_<OPERATION>, where
10927     <OPERATION> is the name (in all capital letters) of the
10928     user interface routine (e.g., MatMult() -> MATOP_MULT).
10929 
10930     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10931 
10932 .keywords: matrix, get, operation
10933 
10934 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10935 @*/
10936 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10937 {
10938   PetscFunctionBegin;
10939   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10940   *f = (((void (**)(void))mat->ops)[op]);
10941   PetscFunctionReturn(0);
10942 }
10943 
10944 /*@
10945     MatHasOperation - Determines whether the given matrix supports the particular
10946     operation.
10947 
10948    Not Collective
10949 
10950    Input Parameters:
10951 +  mat - the matrix
10952 -  op - the operation, for example, MATOP_GET_DIAGONAL
10953 
10954    Output Parameter:
10955 .  has - either PETSC_TRUE or PETSC_FALSE
10956 
10957    Level: advanced
10958 
10959    Notes:
10960    See the file include/petscmat.h for a complete list of matrix
10961    operations, which all have the form MATOP_<OPERATION>, where
10962    <OPERATION> is the name (in all capital letters) of the
10963    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10964 
10965 .keywords: matrix, has, operation
10966 
10967 .seealso: MatCreateShell()
10968 @*/
10969 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10970 {
10971   PetscErrorCode ierr;
10972 
10973   PetscFunctionBegin;
10974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10975   PetscValidType(mat,1);
10976   PetscValidPointer(has,3);
10977   if (mat->ops->hasoperation) {
10978     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10979   } else {
10980     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10981     else {
10982       *has = PETSC_FALSE;
10983       if (op == MATOP_CREATE_SUBMATRIX) {
10984         PetscMPIInt size;
10985 
10986         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10987         if (size == 1) {
10988           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10989         }
10990       }
10991     }
10992   }
10993   PetscFunctionReturn(0);
10994 }
10995 
10996 /*@
10997     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10998     of the matrix are congruent
10999 
11000    Collective on mat
11001 
11002    Input Parameters:
11003 .  mat - the matrix
11004 
11005    Output Parameter:
11006 .  cong - either PETSC_TRUE or PETSC_FALSE
11007 
11008    Level: beginner
11009 
11010    Notes:
11011 
11012 .keywords: matrix, has
11013 
11014 .seealso: MatCreate(), MatSetSizes()
11015 @*/
11016 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11017 {
11018   PetscErrorCode ierr;
11019 
11020   PetscFunctionBegin;
11021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11022   PetscValidType(mat,1);
11023   PetscValidPointer(cong,2);
11024   if (!mat->rmap || !mat->cmap) {
11025     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11026     PetscFunctionReturn(0);
11027   }
11028   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11029     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11030     if (*cong) mat->congruentlayouts = 1;
11031     else       mat->congruentlayouts = 0;
11032   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11033   PetscFunctionReturn(0);
11034 }
11035