xref: /petsc/src/mat/interface/matrix.c (revision 00816365229eff0fcb3567887feb4c4abe2b0e86)
1 /*
2    This is where the abstract matrix operations are defined
3 */
4 
5 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
6 #include <petsc/private/isimpl.h>
7 #include <petsc/private/vecimpl.h>
8 
9 /* Logging support */
10 PetscClassId MAT_CLASSID;
11 PetscClassId MAT_COLORING_CLASSID;
12 PetscClassId MAT_FDCOLORING_CLASSID;
13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14 
15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
23 PetscLogEvent MAT_TransposeColoringCreate;
24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33 PetscLogEvent MAT_GetMultiProcBlock;
34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
35 PetscLogEvent MAT_ViennaCLCopyToGPU;
36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS;
39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
40 
41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
42 
43 /*@
44    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations,
45                   for sparse matrices that already have locations it fills the locations with random numbers
46 
47    Logically Collective on Mat
48 
49    Input Parameters:
50 +  x  - the matrix
51 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52           it will create one internally.
53 
54    Output Parameter:
55 .  x  - the matrix
56 
57    Example of Usage:
58 .vb
59      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60      MatSetRandom(x,rctx);
61      PetscRandomDestroy(rctx);
62 .ve
63 
64    Level: intermediate
65 
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   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name);
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391   PetscFunctionReturn(0);
392 }
393 
394 /*@C
395    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
396 
397    Collective on Mat
398 
399    Input Parameter:
400 .  mat - the matrix
401 
402    Output Parameters:
403 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
404 -   ghosts - the global indices of the ghost points
405 
406    Notes:
407     the nghosts and ghosts are suitable to pass into VecCreateGhost()
408 
409    Level: advanced
410 
411 @*/
412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
413 {
414   PetscErrorCode ierr;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
418   PetscValidType(mat,1);
419   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
420   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
421   if (!mat->ops->getghosts) {
422     if (nghosts) *nghosts = 0;
423     if (ghosts) *ghosts = 0;
424   } else {
425     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
426   }
427   PetscFunctionReturn(0);
428 }
429 
430 
431 /*@
432    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
433 
434    Logically Collective on Mat
435 
436    Input Parameters:
437 .  mat - the matrix
438 
439    Level: advanced
440 
441 
442 .seealso: MatRealPart()
443 @*/
444 PetscErrorCode MatImaginaryPart(Mat mat)
445 {
446   PetscErrorCode ierr;
447 
448   PetscFunctionBegin;
449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
450   PetscValidType(mat,1);
451   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
452   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
453   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
454   MatCheckPreallocated(mat,1);
455   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
456   PetscFunctionReturn(0);
457 }
458 
459 /*@
460    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
461 
462    Not Collective
463 
464    Input Parameter:
465 .  mat - the matrix
466 
467    Output Parameters:
468 +  missing - is any diagonal missing
469 -  dd - first diagonal entry that is missing (optional) on this process
470 
471    Level: advanced
472 
473 
474 .seealso: MatRealPart()
475 @*/
476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
477 {
478   PetscErrorCode ierr;
479 
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
482   PetscValidType(mat,1);
483   PetscValidPointer(missing,2);
484   if (!mat->assembled) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name);
485   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
486   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
487   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
488   PetscFunctionReturn(0);
489 }
490 
491 /*@C
492    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
493    for each row that you get to ensure that your application does
494    not bleed memory.
495 
496    Not Collective
497 
498    Input Parameters:
499 +  mat - the matrix
500 -  row - the row to get
501 
502    Output Parameters:
503 +  ncols -  if not NULL, the number of nonzeros in the row
504 .  cols - if not NULL, the column numbers
505 -  vals - if not NULL, the values
506 
507    Notes:
508    This routine is provided for people who need to have direct access
509    to the structure of a matrix.  We hope that we provide enough
510    high-level matrix routines that few users will need it.
511 
512    MatGetRow() always returns 0-based column indices, regardless of
513    whether the internal representation is 0-based (default) or 1-based.
514 
515    For better efficiency, set cols and/or vals to NULL if you do
516    not wish to extract these quantities.
517 
518    The user can only examine the values extracted with MatGetRow();
519    the values cannot be altered.  To change the matrix entries, one
520    must use MatSetValues().
521 
522    You can only have one call to MatGetRow() outstanding for a particular
523    matrix at a time, per processor. MatGetRow() can only obtain rows
524    associated with the given processor, it cannot get rows from the
525    other processors; for that we suggest using MatCreateSubMatrices(), then
526    MatGetRow() on the submatrix. The row index passed to MatGetRow()
527    is in the global number of rows.
528 
529    Fortran Notes:
530    The calling sequence from Fortran is
531 .vb
532    MatGetRow(matrix,row,ncols,cols,values,ierr)
533          Mat     matrix (input)
534          integer row    (input)
535          integer ncols  (output)
536          integer cols(maxcols) (output)
537          double precision (or double complex) values(maxcols) output
538 .ve
539    where maxcols >= maximum nonzeros in any row of the matrix.
540 
541 
542    Caution:
543    Do not try to change the contents of the output arrays (cols and vals).
544    In some cases, this may corrupt the matrix.
545 
546    Level: advanced
547 
548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
549 @*/
550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
551 {
552   PetscErrorCode ierr;
553   PetscInt       incols;
554 
555   PetscFunctionBegin;
556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
557   PetscValidType(mat,1);
558   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
559   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
560   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
561   MatCheckPreallocated(mat,1);
562   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
563   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
564   if (ncols) *ncols = incols;
565   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
566   PetscFunctionReturn(0);
567 }
568 
569 /*@
570    MatConjugate - replaces the matrix values with their complex conjugates
571 
572    Logically Collective on Mat
573 
574    Input Parameters:
575 .  mat - the matrix
576 
577    Level: advanced
578 
579 .seealso:  VecConjugate()
580 @*/
581 PetscErrorCode MatConjugate(Mat mat)
582 {
583 #if defined(PETSC_USE_COMPLEX)
584   PetscErrorCode ierr;
585 
586   PetscFunctionBegin;
587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
588   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
589   if (!mat->ops->conjugate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name);
590   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
591 #else
592   PetscFunctionBegin;
593 #endif
594   PetscFunctionReturn(0);
595 }
596 
597 /*@C
598    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
599 
600    Not Collective
601 
602    Input Parameters:
603 +  mat - the matrix
604 .  row - the row to get
605 .  ncols, cols - the number of nonzeros and their columns
606 -  vals - if nonzero the column values
607 
608    Notes:
609    This routine should be called after you have finished examining the entries.
610 
611    This routine zeros out ncols, cols, and vals. This is to prevent accidental
612    us of the array after it has been restored. If you pass NULL, it will
613    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
614 
615    Fortran Notes:
616    The calling sequence from Fortran is
617 .vb
618    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
619       Mat     matrix (input)
620       integer row    (input)
621       integer ncols  (output)
622       integer cols(maxcols) (output)
623       double precision (or double complex) values(maxcols) output
624 .ve
625    Where maxcols >= maximum nonzeros in any row of the matrix.
626 
627    In Fortran MatRestoreRow() MUST be called after MatGetRow()
628    before another call to MatGetRow() can be made.
629 
630    Level: advanced
631 
632 .seealso:  MatGetRow()
633 @*/
634 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
635 {
636   PetscErrorCode ierr;
637 
638   PetscFunctionBegin;
639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
640   if (ncols) PetscValidIntPointer(ncols,3);
641   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
642   if (!mat->ops->restorerow) PetscFunctionReturn(0);
643   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
644   if (ncols) *ncols = 0;
645   if (cols)  *cols = NULL;
646   if (vals)  *vals = NULL;
647   PetscFunctionReturn(0);
648 }
649 
650 /*@
651    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
652    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
653 
654    Not Collective
655 
656    Input Parameters:
657 .  mat - the matrix
658 
659    Notes:
660    The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format.
661 
662    Level: advanced
663 
664 .seealso: MatRestoreRowUpperTriangular()
665 @*/
666 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
667 {
668   PetscErrorCode ierr;
669 
670   PetscFunctionBegin;
671   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
672   PetscValidType(mat,1);
673   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
674   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
675   MatCheckPreallocated(mat,1);
676   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
677   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
678   PetscFunctionReturn(0);
679 }
680 
681 /*@
682    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
683 
684    Not Collective
685 
686    Input Parameters:
687 .  mat - the matrix
688 
689    Notes:
690    This routine should be called after you have finished MatGetRow/MatRestoreRow().
691 
692 
693    Level: advanced
694 
695 .seealso:  MatGetRowUpperTriangular()
696 @*/
697 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
698 {
699   PetscErrorCode ierr;
700 
701   PetscFunctionBegin;
702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
703   PetscValidType(mat,1);
704   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
705   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
706   MatCheckPreallocated(mat,1);
707   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
708   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
709   PetscFunctionReturn(0);
710 }
711 
712 /*@C
713    MatSetOptionsPrefix - Sets the prefix used for searching for all
714    Mat options in the database.
715 
716    Logically Collective on Mat
717 
718    Input Parameter:
719 +  A - the Mat context
720 -  prefix - the prefix to prepend to all option names
721 
722    Notes:
723    A hyphen (-) must NOT be given at the beginning of the prefix name.
724    The first character of all runtime options is AUTOMATICALLY the hyphen.
725 
726    Level: advanced
727 
728 .seealso: MatSetFromOptions()
729 @*/
730 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
731 {
732   PetscErrorCode ierr;
733 
734   PetscFunctionBegin;
735   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
736   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
737   PetscFunctionReturn(0);
738 }
739 
740 /*@C
741    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
742    Mat options in the database.
743 
744    Logically Collective on Mat
745 
746    Input Parameters:
747 +  A - the Mat context
748 -  prefix - the prefix to prepend to all option names
749 
750    Notes:
751    A hyphen (-) must NOT be given at the beginning of the prefix name.
752    The first character of all runtime options is AUTOMATICALLY the hyphen.
753 
754    Level: advanced
755 
756 .seealso: MatGetOptionsPrefix()
757 @*/
758 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
759 {
760   PetscErrorCode ierr;
761 
762   PetscFunctionBegin;
763   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
764   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
765   PetscFunctionReturn(0);
766 }
767 
768 /*@C
769    MatGetOptionsPrefix - Gets the prefix used for searching for all
770    Mat options in the database.
771 
772    Not Collective
773 
774    Input Parameter:
775 .  A - the Mat context
776 
777    Output Parameter:
778 .  prefix - pointer to the prefix string used
779 
780    Notes:
781     On the fortran side, the user should pass in a string 'prefix' of
782    sufficient length to hold the prefix.
783 
784    Level: advanced
785 
786 .seealso: MatAppendOptionsPrefix()
787 @*/
788 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
789 {
790   PetscErrorCode ierr;
791 
792   PetscFunctionBegin;
793   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
794   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
795   PetscFunctionReturn(0);
796 }
797 
798 /*@
799    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
800 
801    Collective on Mat
802 
803    Input Parameters:
804 .  A - the Mat context
805 
806    Notes:
807    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
808    Currently support MPIAIJ and SEQAIJ.
809 
810    Level: beginner
811 
812 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
813 @*/
814 PetscErrorCode MatResetPreallocation(Mat A)
815 {
816   PetscErrorCode ierr;
817 
818   PetscFunctionBegin;
819   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
820   PetscValidType(A,1);
821   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
822   PetscFunctionReturn(0);
823 }
824 
825 
826 /*@
827    MatSetUp - Sets up the internal matrix data structures for later use.
828 
829    Collective on Mat
830 
831    Input Parameters:
832 .  A - the Mat context
833 
834    Notes:
835    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
836 
837    If a suitable preallocation routine is used, this function does not need to be called.
838 
839    See the Performance chapter of the PETSc users manual for how to preallocate matrices
840 
841    Level: beginner
842 
843 .seealso: MatCreate(), MatDestroy()
844 @*/
845 PetscErrorCode MatSetUp(Mat A)
846 {
847   PetscMPIInt    size;
848   PetscErrorCode ierr;
849 
850   PetscFunctionBegin;
851   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
852   if (!((PetscObject)A)->type_name) {
853     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
854     if (size == 1) {
855       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
856     } else {
857       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
858     }
859   }
860   if (!A->preallocated && A->ops->setup) {
861     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
862     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
863   }
864   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
865   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
866   A->preallocated = PETSC_TRUE;
867   PetscFunctionReturn(0);
868 }
869 
870 #if defined(PETSC_HAVE_SAWS)
871 #include <petscviewersaws.h>
872 #endif
873 
874 /*@C
875    MatViewFromOptions - View from Options
876 
877    Collective on Mat
878 
879    Input Parameters:
880 +  A - the Mat context
881 .  obj - Optional object
882 -  name - command line option
883 
884    Level: intermediate
885 .seealso:  Mat, MatView, PetscObjectViewFromOptions(), MatCreate()
886 @*/
887 PetscErrorCode  MatViewFromOptions(Mat A,PetscObject obj,const char name[])
888 {
889   PetscErrorCode ierr;
890 
891   PetscFunctionBegin;
892   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
893   ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
894   PetscFunctionReturn(0);
895 }
896 
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     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
955     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
956 
957     See the manual page for MatLoad() for the exact format of the binary file when the binary
958       viewer is used.
959 
960       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
961       viewer is used.
962 
963       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
964       and then use the following mouse functions.
965 + left mouse: zoom in
966 . middle mouse: zoom out
967 - right mouse: continue with the simulation
968 
969 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
970           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
971 @*/
972 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
973 {
974   PetscErrorCode    ierr;
975   PetscInt          rows,cols,rbs,cbs;
976   PetscBool         isascii,isstring,issaws;
977   PetscViewerFormat format;
978   PetscMPIInt       size;
979 
980   PetscFunctionBegin;
981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
982   PetscValidType(mat,1);
983   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);}
984   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
985   PetscCheckSameComm(mat,1,viewer,2);
986   MatCheckPreallocated(mat,1);
987 
988   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
989   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
990   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
991 
992   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
993   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
994   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
995   if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
996     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail");
997   }
998 
999   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1000   if (isascii) {
1001     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1002     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1003     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1004       MatNullSpace nullsp,transnullsp;
1005 
1006       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1007       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1008       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1009       if (rbs != 1 || cbs != 1) {
1010         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1011         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1012       } else {
1013         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1014       }
1015       if (mat->factortype) {
1016         MatSolverType solver;
1017         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1018         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1019       }
1020       if (mat->ops->getinfo) {
1021         MatInfo info;
1022         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1023         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1024         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1025       }
1026       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1027       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1028       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1029       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1030       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1031       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1032     }
1033   } else if (issaws) {
1034 #if defined(PETSC_HAVE_SAWS)
1035     PetscMPIInt rank;
1036 
1037     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1038     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1039     if (!((PetscObject)mat)->amsmem && !rank) {
1040       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1041     }
1042 #endif
1043   } else if (isstring) {
1044     const char *type;
1045     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1046     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1047     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1048   }
1049   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1050     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1051     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1052     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1053   } else if (mat->ops->view) {
1054     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1055     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1056     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1057   }
1058   if (isascii) {
1059     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1060     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1061       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1062     }
1063   }
1064   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1065   PetscFunctionReturn(0);
1066 }
1067 
1068 #if defined(PETSC_USE_DEBUG)
1069 #include <../src/sys/totalview/tv_data_display.h>
1070 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1071 {
1072   TV_add_row("Local rows", "int", &mat->rmap->n);
1073   TV_add_row("Local columns", "int", &mat->cmap->n);
1074   TV_add_row("Global rows", "int", &mat->rmap->N);
1075   TV_add_row("Global columns", "int", &mat->cmap->N);
1076   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1077   return TV_format_OK;
1078 }
1079 #endif
1080 
1081 /*@C
1082    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1083    with MatView().  The matrix format is determined from the options database.
1084    Generates a parallel MPI matrix if the communicator has more than one
1085    processor.  The default matrix type is AIJ.
1086 
1087    Collective on PetscViewer
1088 
1089    Input Parameters:
1090 +  mat - the newly loaded matrix, this needs to have been created with MatCreate()
1091             or some related function before a call to MatLoad()
1092 -  viewer - binary/HDF5 file viewer
1093 
1094    Options Database Keys:
1095    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1096    block size
1097 .    -matload_block_size <bs>
1098 
1099    Level: beginner
1100 
1101    Notes:
1102    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1103    Mat before calling this routine if you wish to set it from the options database.
1104 
1105    MatLoad() automatically loads into the options database any options
1106    given in the file filename.info where filename is the name of the file
1107    that was passed to the PetscViewerBinaryOpen(). The options in the info
1108    file will be ignored if you use the -viewer_binary_skip_info option.
1109 
1110    If the type or size of mat is not set before a call to MatLoad, PETSc
1111    sets the default matrix type AIJ and sets the local and global sizes.
1112    If type and/or size is already set, then the same are used.
1113 
1114    In parallel, each processor can load a subset of rows (or the
1115    entire matrix).  This routine is especially useful when a large
1116    matrix is stored on disk and only part of it is desired on each
1117    processor.  For example, a parallel solver may access only some of
1118    the rows from each processor.  The algorithm used here reads
1119    relatively small blocks of data rather than reading the entire
1120    matrix and then subsetting it.
1121 
1122    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1123    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1124    or the sequence like
1125 $    PetscViewer v;
1126 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1127 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1128 $    PetscViewerSetFromOptions(v);
1129 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1130 $    PetscViewerFileSetName(v,"datafile");
1131    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1132 $ -viewer_type {binary,hdf5}
1133 
1134    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1135    and src/mat/examples/tutorials/ex10.c with the second approach.
1136 
1137    Notes about the PETSc binary format:
1138    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1139    is read onto rank 0 and then shipped to its destination rank, one after another.
1140    Multiple objects, both matrices and vectors, can be stored within the same file.
1141    Their PetscObject name is ignored; they are loaded in the order of their storage.
1142 
1143    Most users should not need to know the details of the binary storage
1144    format, since MatLoad() and MatView() completely hide these details.
1145    But for anyone who's interested, the standard binary matrix storage
1146    format is
1147 
1148 $    PetscInt    MAT_FILE_CLASSID
1149 $    PetscInt    number of rows
1150 $    PetscInt    number of columns
1151 $    PetscInt    total number of nonzeros
1152 $    PetscInt    *number nonzeros in each row
1153 $    PetscInt    *column indices of all nonzeros (starting index is zero)
1154 $    PetscScalar *values of all nonzeros
1155 
1156    PETSc automatically does the byte swapping for
1157 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1158 linux, Windows and the paragon; thus if you write your own binary
1159 read/write routines you have to swap the bytes; see PetscBinaryRead()
1160 and PetscBinaryWrite() to see how this may be done.
1161 
1162    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1163    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1164    Each processor's chunk is loaded independently by its owning rank.
1165    Multiple objects, both matrices and vectors, can be stored within the same file.
1166    They are looked up by their PetscObject name.
1167 
1168    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1169    by default the same structure and naming of the AIJ arrays and column count
1170    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1171 $    save example.mat A b -v7.3
1172    can be directly read by this routine (see Reference 1 for details).
1173    Note that depending on your MATLAB version, this format might be a default,
1174    otherwise you can set it as default in Preferences.
1175 
1176    Unless -nocompression flag is used to save the file in MATLAB,
1177    PETSc must be configured with ZLIB package.
1178 
1179    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1180 
1181    Current HDF5 (MAT-File) limitations:
1182    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1183 
1184    Corresponding MatView() is not yet implemented.
1185 
1186    The loaded matrix is actually a transpose of the original one in MATLAB,
1187    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1188    With this format, matrix is automatically transposed by PETSc,
1189    unless the matrix is marked as SPD or symmetric
1190    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1191 
1192    References:
1193 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1194 
1195 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1196 
1197  @*/
1198 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer)
1199 {
1200   PetscErrorCode ierr;
1201   PetscBool      flg;
1202 
1203   PetscFunctionBegin;
1204   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1205   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1206 
1207   if (!((PetscObject)mat)->type_name) {
1208     ierr = MatSetType(mat,MATAIJ);CHKERRQ(ierr);
1209   }
1210 
1211   flg  = PETSC_FALSE;
1212   ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1213   if (flg) {
1214     ierr = MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1215     ierr = MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1216   }
1217   flg  = PETSC_FALSE;
1218   ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1219   if (flg) {
1220     ierr = MatSetOption(mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1221   }
1222 
1223   if (!mat->ops->load) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name);
1224   ierr = PetscLogEventBegin(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1225   ierr = (*mat->ops->load)(mat,viewer);CHKERRQ(ierr);
1226   ierr = PetscLogEventEnd(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1227   PetscFunctionReturn(0);
1228 }
1229 
1230 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1231 {
1232   PetscErrorCode ierr;
1233   Mat_Redundant  *redund = *redundant;
1234   PetscInt       i;
1235 
1236   PetscFunctionBegin;
1237   if (redund){
1238     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1239       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1240       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1241       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1242     } else {
1243       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1244       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1245       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1246       for (i=0; i<redund->nrecvs; i++) {
1247         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1248         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1249       }
1250       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1251     }
1252 
1253     if (redund->subcomm) {
1254       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1255     }
1256     ierr = PetscFree(redund);CHKERRQ(ierr);
1257   }
1258   PetscFunctionReturn(0);
1259 }
1260 
1261 /*@
1262    MatDestroy - Frees space taken by a matrix.
1263 
1264    Collective on Mat
1265 
1266    Input Parameter:
1267 .  A - the matrix
1268 
1269    Level: beginner
1270 
1271 @*/
1272 PetscErrorCode MatDestroy(Mat *A)
1273 {
1274   PetscErrorCode ierr;
1275 
1276   PetscFunctionBegin;
1277   if (!*A) PetscFunctionReturn(0);
1278   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1279   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1280 
1281   /* if memory was published with SAWs then destroy it */
1282   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1283   if ((*A)->ops->destroy) {
1284     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1285   }
1286 
1287   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1288   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1289   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1290   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1291   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1292   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1293   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1294   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1295   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1296   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1297   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1298   PetscFunctionReturn(0);
1299 }
1300 
1301 /*@C
1302    MatSetValues - Inserts or adds a block of values into a matrix.
1303    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1304    MUST be called after all calls to MatSetValues() have been completed.
1305 
1306    Not Collective
1307 
1308    Input Parameters:
1309 +  mat - the matrix
1310 .  v - a logically two-dimensional array of values
1311 .  m, idxm - the number of rows and their global indices
1312 .  n, idxn - the number of columns and their global indices
1313 -  addv - either ADD_VALUES or INSERT_VALUES, where
1314    ADD_VALUES adds values to any existing entries, and
1315    INSERT_VALUES replaces existing entries with new values
1316 
1317    Notes:
1318    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1319       MatSetUp() before using this routine
1320 
1321    By default the values, v, are row-oriented. See MatSetOption() for other options.
1322 
1323    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1324    options cannot be mixed without intervening calls to the assembly
1325    routines.
1326 
1327    MatSetValues() uses 0-based row and column numbers in Fortran
1328    as well as in C.
1329 
1330    Negative indices may be passed in idxm and idxn, these rows and columns are
1331    simply ignored. This allows easily inserting element stiffness matrices
1332    with homogeneous Dirchlet boundary conditions that you don't want represented
1333    in the matrix.
1334 
1335    Efficiency Alert:
1336    The routine MatSetValuesBlocked() may offer much better efficiency
1337    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1338 
1339    Level: beginner
1340 
1341    Developer Notes:
1342     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1343                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1344 
1345 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1346           InsertMode, INSERT_VALUES, ADD_VALUES
1347 @*/
1348 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1349 {
1350   PetscErrorCode ierr;
1351 #if defined(PETSC_USE_DEBUG)
1352   PetscInt       i,j;
1353 #endif
1354 
1355   PetscFunctionBeginHot;
1356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1357   PetscValidType(mat,1);
1358   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1359   PetscValidIntPointer(idxm,3);
1360   PetscValidIntPointer(idxn,5);
1361   MatCheckPreallocated(mat,1);
1362 
1363   if (mat->insertmode == NOT_SET_VALUES) {
1364     mat->insertmode = addv;
1365   }
1366 #if defined(PETSC_USE_DEBUG)
1367   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1368   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1369   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1370 
1371   for (i=0; i<m; i++) {
1372     for (j=0; j<n; j++) {
1373       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1374 #if defined(PETSC_USE_COMPLEX)
1375         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]);
1376 #else
1377         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1378 #endif
1379     }
1380   }
1381 #endif
1382 
1383   if (mat->assembled) {
1384     mat->was_assembled = PETSC_TRUE;
1385     mat->assembled     = PETSC_FALSE;
1386   }
1387   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1388   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1389   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1390   PetscFunctionReturn(0);
1391 }
1392 
1393 
1394 /*@
1395    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1396         values into a matrix
1397 
1398    Not Collective
1399 
1400    Input Parameters:
1401 +  mat - the matrix
1402 .  row - the (block) row to set
1403 -  v - a logically two-dimensional array of values
1404 
1405    Notes:
1406    By the values, v, are column-oriented (for the block version) and sorted
1407 
1408    All the nonzeros in the row must be provided
1409 
1410    The matrix must have previously had its column indices set
1411 
1412    The row must belong to this process
1413 
1414    Level: intermediate
1415 
1416 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1417           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1418 @*/
1419 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1420 {
1421   PetscErrorCode ierr;
1422   PetscInt       globalrow;
1423 
1424   PetscFunctionBegin;
1425   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1426   PetscValidType(mat,1);
1427   PetscValidScalarPointer(v,2);
1428   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1429   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1430   PetscFunctionReturn(0);
1431 }
1432 
1433 /*@
1434    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1435         values into a matrix
1436 
1437    Not Collective
1438 
1439    Input Parameters:
1440 +  mat - the matrix
1441 .  row - the (block) row to set
1442 -  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
1443 
1444    Notes:
1445    The values, v, are column-oriented for the block version.
1446 
1447    All the nonzeros in the row must be provided
1448 
1449    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1450 
1451    The row must belong to this process
1452 
1453    Level: advanced
1454 
1455 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1456           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1457 @*/
1458 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1459 {
1460   PetscErrorCode ierr;
1461 
1462   PetscFunctionBeginHot;
1463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1464   PetscValidType(mat,1);
1465   MatCheckPreallocated(mat,1);
1466   PetscValidScalarPointer(v,2);
1467 #if defined(PETSC_USE_DEBUG)
1468   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1469   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1470 #endif
1471   mat->insertmode = INSERT_VALUES;
1472 
1473   if (mat->assembled) {
1474     mat->was_assembled = PETSC_TRUE;
1475     mat->assembled     = PETSC_FALSE;
1476   }
1477   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1478   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1479   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1480   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1481   PetscFunctionReturn(0);
1482 }
1483 
1484 /*@
1485    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1486      Using structured grid indexing
1487 
1488    Not Collective
1489 
1490    Input Parameters:
1491 +  mat - the matrix
1492 .  m - number of rows being entered
1493 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1494 .  n - number of columns being entered
1495 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1496 .  v - a logically two-dimensional array of values
1497 -  addv - either ADD_VALUES or INSERT_VALUES, where
1498    ADD_VALUES adds values to any existing entries, and
1499    INSERT_VALUES replaces existing entries with new values
1500 
1501    Notes:
1502    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1503 
1504    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1505    options cannot be mixed without intervening calls to the assembly
1506    routines.
1507 
1508    The grid coordinates are across the entire grid, not just the local portion
1509 
1510    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1511    as well as in C.
1512 
1513    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1514 
1515    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1516    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1517 
1518    The columns and rows in the stencil passed in MUST be contained within the
1519    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1520    if you create a DMDA with an overlap of one grid level and on a particular process its first
1521    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1522    first i index you can use in your column and row indices in MatSetStencil() is 5.
1523 
1524    In Fortran idxm and idxn should be declared as
1525 $     MatStencil idxm(4,m),idxn(4,n)
1526    and the values inserted using
1527 $    idxm(MatStencil_i,1) = i
1528 $    idxm(MatStencil_j,1) = j
1529 $    idxm(MatStencil_k,1) = k
1530 $    idxm(MatStencil_c,1) = c
1531    etc
1532 
1533    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1534    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1535    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1536    DM_BOUNDARY_PERIODIC boundary type.
1537 
1538    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
1539    a single value per point) you can skip filling those indices.
1540 
1541    Inspired by the structured grid interface to the HYPRE package
1542    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1543 
1544    Efficiency Alert:
1545    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1546    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1547 
1548    Level: beginner
1549 
1550 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1551           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1552 @*/
1553 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1554 {
1555   PetscErrorCode ierr;
1556   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1557   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1558   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1559 
1560   PetscFunctionBegin;
1561   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1562   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1563   PetscValidType(mat,1);
1564   PetscValidIntPointer(idxm,3);
1565   PetscValidIntPointer(idxn,5);
1566 
1567   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1568     jdxm = buf; jdxn = buf+m;
1569   } else {
1570     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1571     jdxm = bufm; jdxn = bufn;
1572   }
1573   for (i=0; i<m; i++) {
1574     for (j=0; j<3-sdim; j++) dxm++;
1575     tmp = *dxm++ - starts[0];
1576     for (j=0; j<dim-1; j++) {
1577       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1578       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1579     }
1580     if (mat->stencil.noc) dxm++;
1581     jdxm[i] = tmp;
1582   }
1583   for (i=0; i<n; i++) {
1584     for (j=0; j<3-sdim; j++) dxn++;
1585     tmp = *dxn++ - starts[0];
1586     for (j=0; j<dim-1; j++) {
1587       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1588       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1589     }
1590     if (mat->stencil.noc) dxn++;
1591     jdxn[i] = tmp;
1592   }
1593   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1594   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1595   PetscFunctionReturn(0);
1596 }
1597 
1598 /*@
1599    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1600      Using structured grid indexing
1601 
1602    Not Collective
1603 
1604    Input Parameters:
1605 +  mat - the matrix
1606 .  m - number of rows being entered
1607 .  idxm - grid coordinates for matrix rows being entered
1608 .  n - number of columns being entered
1609 .  idxn - grid coordinates for matrix columns being entered
1610 .  v - a logically two-dimensional array of values
1611 -  addv - either ADD_VALUES or INSERT_VALUES, where
1612    ADD_VALUES adds values to any existing entries, and
1613    INSERT_VALUES replaces existing entries with new values
1614 
1615    Notes:
1616    By default the values, v, are row-oriented and unsorted.
1617    See MatSetOption() for other options.
1618 
1619    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1620    options cannot be mixed without intervening calls to the assembly
1621    routines.
1622 
1623    The grid coordinates are across the entire grid, not just the local portion
1624 
1625    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1626    as well as in C.
1627 
1628    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1629 
1630    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1631    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1632 
1633    The columns and rows in the stencil passed in MUST be contained within the
1634    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1635    if you create a DMDA with an overlap of one grid level and on a particular process its first
1636    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1637    first i index you can use in your column and row indices in MatSetStencil() is 5.
1638 
1639    In Fortran idxm and idxn should be declared as
1640 $     MatStencil idxm(4,m),idxn(4,n)
1641    and the values inserted using
1642 $    idxm(MatStencil_i,1) = i
1643 $    idxm(MatStencil_j,1) = j
1644 $    idxm(MatStencil_k,1) = k
1645    etc
1646 
1647    Negative indices may be passed in idxm and idxn, these rows and columns are
1648    simply ignored. This allows easily inserting element stiffness matrices
1649    with homogeneous Dirchlet boundary conditions that you don't want represented
1650    in the matrix.
1651 
1652    Inspired by the structured grid interface to the HYPRE package
1653    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1654 
1655    Level: beginner
1656 
1657 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1658           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1659           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1660 @*/
1661 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1662 {
1663   PetscErrorCode ierr;
1664   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1665   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1666   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1667 
1668   PetscFunctionBegin;
1669   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1670   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1671   PetscValidType(mat,1);
1672   PetscValidIntPointer(idxm,3);
1673   PetscValidIntPointer(idxn,5);
1674   PetscValidScalarPointer(v,6);
1675 
1676   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1677     jdxm = buf; jdxn = buf+m;
1678   } else {
1679     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1680     jdxm = bufm; jdxn = bufn;
1681   }
1682   for (i=0; i<m; i++) {
1683     for (j=0; j<3-sdim; j++) dxm++;
1684     tmp = *dxm++ - starts[0];
1685     for (j=0; j<sdim-1; j++) {
1686       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1687       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1688     }
1689     dxm++;
1690     jdxm[i] = tmp;
1691   }
1692   for (i=0; i<n; i++) {
1693     for (j=0; j<3-sdim; j++) dxn++;
1694     tmp = *dxn++ - starts[0];
1695     for (j=0; j<sdim-1; j++) {
1696       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1697       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1698     }
1699     dxn++;
1700     jdxn[i] = tmp;
1701   }
1702   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1703   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1704   PetscFunctionReturn(0);
1705 }
1706 
1707 /*@
1708    MatSetStencil - Sets the grid information for setting values into a matrix via
1709         MatSetValuesStencil()
1710 
1711    Not Collective
1712 
1713    Input Parameters:
1714 +  mat - the matrix
1715 .  dim - dimension of the grid 1, 2, or 3
1716 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1717 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1718 -  dof - number of degrees of freedom per node
1719 
1720 
1721    Inspired by the structured grid interface to the HYPRE package
1722    (www.llnl.gov/CASC/hyper)
1723 
1724    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1725    user.
1726 
1727    Level: beginner
1728 
1729 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1730           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1731 @*/
1732 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1733 {
1734   PetscInt i;
1735 
1736   PetscFunctionBegin;
1737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1738   PetscValidIntPointer(dims,3);
1739   PetscValidIntPointer(starts,4);
1740 
1741   mat->stencil.dim = dim + (dof > 1);
1742   for (i=0; i<dim; i++) {
1743     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1744     mat->stencil.starts[i] = starts[dim-i-1];
1745   }
1746   mat->stencil.dims[dim]   = dof;
1747   mat->stencil.starts[dim] = 0;
1748   mat->stencil.noc         = (PetscBool)(dof == 1);
1749   PetscFunctionReturn(0);
1750 }
1751 
1752 /*@C
1753    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1754 
1755    Not Collective
1756 
1757    Input Parameters:
1758 +  mat - the matrix
1759 .  v - a logically two-dimensional array of values
1760 .  m, idxm - the number of block rows and their global block indices
1761 .  n, idxn - the number of block columns and their global block indices
1762 -  addv - either ADD_VALUES or INSERT_VALUES, where
1763    ADD_VALUES adds values to any existing entries, and
1764    INSERT_VALUES replaces existing entries with new values
1765 
1766    Notes:
1767    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1768    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1769 
1770    The m and n count the NUMBER of blocks in the row direction and column direction,
1771    NOT the total number of rows/columns; for example, if the block size is 2 and
1772    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1773    The values in idxm would be 1 2; that is the first index for each block divided by
1774    the block size.
1775 
1776    Note that you must call MatSetBlockSize() when constructing this matrix (before
1777    preallocating it).
1778 
1779    By default the values, v, are row-oriented, so the layout of
1780    v is the same as for MatSetValues(). See MatSetOption() for other options.
1781 
1782    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1783    options cannot be mixed without intervening calls to the assembly
1784    routines.
1785 
1786    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1787    as well as in C.
1788 
1789    Negative indices may be passed in idxm and idxn, these rows and columns are
1790    simply ignored. This allows easily inserting element stiffness matrices
1791    with homogeneous Dirchlet boundary conditions that you don't want represented
1792    in the matrix.
1793 
1794    Each time an entry is set within a sparse matrix via MatSetValues(),
1795    internal searching must be done to determine where to place the
1796    data in the matrix storage space.  By instead inserting blocks of
1797    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1798    reduced.
1799 
1800    Example:
1801 $   Suppose m=n=2 and block size(bs) = 2 The array is
1802 $
1803 $   1  2  | 3  4
1804 $   5  6  | 7  8
1805 $   - - - | - - -
1806 $   9  10 | 11 12
1807 $   13 14 | 15 16
1808 $
1809 $   v[] should be passed in like
1810 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1811 $
1812 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1813 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1814 
1815    Level: intermediate
1816 
1817 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1818 @*/
1819 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1820 {
1821   PetscErrorCode ierr;
1822 
1823   PetscFunctionBeginHot;
1824   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1825   PetscValidType(mat,1);
1826   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1827   PetscValidIntPointer(idxm,3);
1828   PetscValidIntPointer(idxn,5);
1829   PetscValidScalarPointer(v,6);
1830   MatCheckPreallocated(mat,1);
1831   if (mat->insertmode == NOT_SET_VALUES) {
1832     mat->insertmode = addv;
1833   }
1834 #if defined(PETSC_USE_DEBUG)
1835   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1836   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1837   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1838 #endif
1839 
1840   if (mat->assembled) {
1841     mat->was_assembled = PETSC_TRUE;
1842     mat->assembled     = PETSC_FALSE;
1843   }
1844   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1845   if (mat->ops->setvaluesblocked) {
1846     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1847   } else {
1848     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1849     PetscInt i,j,bs,cbs;
1850     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1851     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1852       iidxm = buf; iidxn = buf + m*bs;
1853     } else {
1854       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1855       iidxm = bufr; iidxn = bufc;
1856     }
1857     for (i=0; i<m; i++) {
1858       for (j=0; j<bs; j++) {
1859         iidxm[i*bs+j] = bs*idxm[i] + j;
1860       }
1861     }
1862     for (i=0; i<n; i++) {
1863       for (j=0; j<cbs; j++) {
1864         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1865       }
1866     }
1867     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1868     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1869   }
1870   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1871   PetscFunctionReturn(0);
1872 }
1873 
1874 /*@C
1875    MatGetValues - Gets a block of values from a matrix.
1876 
1877    Not Collective; currently only returns a local block
1878 
1879    Input Parameters:
1880 +  mat - the matrix
1881 .  v - a logically two-dimensional array for storing the values
1882 .  m, idxm - the number of rows and their global indices
1883 -  n, idxn - the number of columns and their global indices
1884 
1885    Notes:
1886    The user must allocate space (m*n PetscScalars) for the values, v.
1887    The values, v, are then returned in a row-oriented format,
1888    analogous to that used by default in MatSetValues().
1889 
1890    MatGetValues() uses 0-based row and column numbers in
1891    Fortran as well as in C.
1892 
1893    MatGetValues() requires that the matrix has been assembled
1894    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1895    MatSetValues() and MatGetValues() CANNOT be made in succession
1896    without intermediate matrix assembly.
1897 
1898    Negative row or column indices will be ignored and those locations in v[] will be
1899    left unchanged.
1900 
1901    Level: advanced
1902 
1903 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1904 @*/
1905 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1906 {
1907   PetscErrorCode ierr;
1908 
1909   PetscFunctionBegin;
1910   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1911   PetscValidType(mat,1);
1912   if (!m || !n) PetscFunctionReturn(0);
1913   PetscValidIntPointer(idxm,3);
1914   PetscValidIntPointer(idxn,5);
1915   PetscValidScalarPointer(v,6);
1916   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1917   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1918   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1919   MatCheckPreallocated(mat,1);
1920 
1921   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1922   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1923   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1924   PetscFunctionReturn(0);
1925 }
1926 
1927 /*@C
1928    MatGetValuesLocal - retrieves values into certain locations of a matrix,
1929    using a local numbering of the nodes.
1930 
1931    Not Collective
1932 
1933    Input Parameters:
1934 +  mat - the matrix
1935 .  nrow, irow - number of rows and their local indices
1936 -  ncol, icol - number of columns and their local indices
1937 
1938    Output Parameter:
1939 .  y -  a logically two-dimensional array of values
1940 
1941    Notes:
1942    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1943 
1944    Level: advanced
1945 
1946    Developer Notes:
1947     This is labelled with C so does not automatically generate Fortran stubs and interfaces
1948                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1949 
1950 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1951            MatSetValuesLocal()
1952 @*/
1953 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[])
1954 {
1955   PetscErrorCode ierr;
1956 
1957   PetscFunctionBeginHot;
1958   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1959   PetscValidType(mat,1);
1960   MatCheckPreallocated(mat,1);
1961   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */
1962   PetscValidIntPointer(irow,3);
1963   PetscValidIntPointer(icol,5);
1964 #if defined(PETSC_USE_DEBUG)
1965   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1966   if (!mat->ops->getvalueslocal && !mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1967 #endif
1968   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1969   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1970   if (mat->ops->getvalueslocal) {
1971     ierr = (*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y);CHKERRQ(ierr);
1972   } else {
1973     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1974     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1975       irowm = buf; icolm = buf+nrow;
1976     } else {
1977       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
1978       irowm = bufr; icolm = bufc;
1979     }
1980     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
1981     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
1982     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1983     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1984     ierr = MatGetValues(mat,nrow,irowm,ncol,icolm,y);CHKERRQ(ierr);
1985     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1986   }
1987   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1988   PetscFunctionReturn(0);
1989 }
1990 
1991 /*@
1992   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1993   the same size. Currently, this can only be called once and creates the given matrix.
1994 
1995   Not Collective
1996 
1997   Input Parameters:
1998 + mat - the matrix
1999 . nb - the number of blocks
2000 . bs - the number of rows (and columns) in each block
2001 . rows - a concatenation of the rows for each block
2002 - v - a concatenation of logically two-dimensional arrays of values
2003 
2004   Notes:
2005   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2006 
2007   Level: advanced
2008 
2009 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2010           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2011 @*/
2012 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2013 {
2014   PetscErrorCode ierr;
2015 
2016   PetscFunctionBegin;
2017   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2018   PetscValidType(mat,1);
2019   PetscValidScalarPointer(rows,4);
2020   PetscValidScalarPointer(v,5);
2021 #if defined(PETSC_USE_DEBUG)
2022   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2023 #endif
2024 
2025   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2026   if (mat->ops->setvaluesbatch) {
2027     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2028   } else {
2029     PetscInt b;
2030     for (b = 0; b < nb; ++b) {
2031       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2032     }
2033   }
2034   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2035   PetscFunctionReturn(0);
2036 }
2037 
2038 /*@
2039    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2040    the routine MatSetValuesLocal() to allow users to insert matrix entries
2041    using a local (per-processor) numbering.
2042 
2043    Not Collective
2044 
2045    Input Parameters:
2046 +  x - the matrix
2047 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2048 - cmapping - column mapping
2049 
2050    Level: intermediate
2051 
2052 
2053 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2054 @*/
2055 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2056 {
2057   PetscErrorCode ierr;
2058 
2059   PetscFunctionBegin;
2060   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2061   PetscValidType(x,1);
2062   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2063   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2064 
2065   if (x->ops->setlocaltoglobalmapping) {
2066     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2067   } else {
2068     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2069     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2070   }
2071   PetscFunctionReturn(0);
2072 }
2073 
2074 
2075 /*@
2076    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2077 
2078    Not Collective
2079 
2080    Input Parameters:
2081 .  A - the matrix
2082 
2083    Output Parameters:
2084 + rmapping - row mapping
2085 - cmapping - column mapping
2086 
2087    Level: advanced
2088 
2089 
2090 .seealso:  MatSetValuesLocal()
2091 @*/
2092 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2093 {
2094   PetscFunctionBegin;
2095   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2096   PetscValidType(A,1);
2097   if (rmapping) PetscValidPointer(rmapping,2);
2098   if (cmapping) PetscValidPointer(cmapping,3);
2099   if (rmapping) *rmapping = A->rmap->mapping;
2100   if (cmapping) *cmapping = A->cmap->mapping;
2101   PetscFunctionReturn(0);
2102 }
2103 
2104 /*@
2105    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2106 
2107    Not Collective
2108 
2109    Input Parameters:
2110 .  A - the matrix
2111 
2112    Output Parameters:
2113 + rmap - row layout
2114 - cmap - column layout
2115 
2116    Level: advanced
2117 
2118 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2119 @*/
2120 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2121 {
2122   PetscFunctionBegin;
2123   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2124   PetscValidType(A,1);
2125   if (rmap) PetscValidPointer(rmap,2);
2126   if (cmap) PetscValidPointer(cmap,3);
2127   if (rmap) *rmap = A->rmap;
2128   if (cmap) *cmap = A->cmap;
2129   PetscFunctionReturn(0);
2130 }
2131 
2132 /*@C
2133    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2134    using a local numbering of the nodes.
2135 
2136    Not Collective
2137 
2138    Input Parameters:
2139 +  mat - the matrix
2140 .  nrow, irow - number of rows and their local indices
2141 .  ncol, icol - number of columns and their local indices
2142 .  y -  a logically two-dimensional array of values
2143 -  addv - either INSERT_VALUES or ADD_VALUES, where
2144    ADD_VALUES adds values to any existing entries, and
2145    INSERT_VALUES replaces existing entries with new values
2146 
2147    Notes:
2148    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2149       MatSetUp() before using this routine
2150 
2151    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2152 
2153    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2154    options cannot be mixed without intervening calls to the assembly
2155    routines.
2156 
2157    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2158    MUST be called after all calls to MatSetValuesLocal() have been completed.
2159 
2160    Level: intermediate
2161 
2162    Developer Notes:
2163     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2165 
2166 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2167            MatSetValueLocal(), MatGetValuesLocal()
2168 @*/
2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2170 {
2171   PetscErrorCode ierr;
2172 
2173   PetscFunctionBeginHot;
2174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2175   PetscValidType(mat,1);
2176   MatCheckPreallocated(mat,1);
2177   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2178   PetscValidIntPointer(irow,3);
2179   PetscValidIntPointer(icol,5);
2180   if (mat->insertmode == NOT_SET_VALUES) {
2181     mat->insertmode = addv;
2182   }
2183 #if defined(PETSC_USE_DEBUG)
2184   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2185   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2186   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2187 #endif
2188 
2189   if (mat->assembled) {
2190     mat->was_assembled = PETSC_TRUE;
2191     mat->assembled     = PETSC_FALSE;
2192   }
2193   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2194   if (mat->ops->setvalueslocal) {
2195     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2196   } else {
2197     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2198     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2199       irowm = buf; icolm = buf+nrow;
2200     } else {
2201       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2202       irowm = bufr; icolm = bufc;
2203     }
2204     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2205     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2206     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2207     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2208     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2209     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2210   }
2211   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2212   PetscFunctionReturn(0);
2213 }
2214 
2215 /*@C
2216    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2217    using a local ordering of the nodes a block at a time.
2218 
2219    Not Collective
2220 
2221    Input Parameters:
2222 +  x - the matrix
2223 .  nrow, irow - number of rows and their local indices
2224 .  ncol, icol - number of columns and their local indices
2225 .  y -  a logically two-dimensional array of values
2226 -  addv - either INSERT_VALUES or ADD_VALUES, where
2227    ADD_VALUES adds values to any existing entries, and
2228    INSERT_VALUES replaces existing entries with new values
2229 
2230    Notes:
2231    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2232       MatSetUp() before using this routine
2233 
2234    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2235       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2236 
2237    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2238    options cannot be mixed without intervening calls to the assembly
2239    routines.
2240 
2241    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2242    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2243 
2244    Level: intermediate
2245 
2246    Developer Notes:
2247     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2248                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2249 
2250 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2251            MatSetValuesLocal(),  MatSetValuesBlocked()
2252 @*/
2253 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2254 {
2255   PetscErrorCode ierr;
2256 
2257   PetscFunctionBeginHot;
2258   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2259   PetscValidType(mat,1);
2260   MatCheckPreallocated(mat,1);
2261   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2262   PetscValidIntPointer(irow,3);
2263   PetscValidIntPointer(icol,5);
2264   PetscValidScalarPointer(y,6);
2265   if (mat->insertmode == NOT_SET_VALUES) {
2266     mat->insertmode = addv;
2267   }
2268 #if defined(PETSC_USE_DEBUG)
2269   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2270   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2271   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);
2272 #endif
2273 
2274   if (mat->assembled) {
2275     mat->was_assembled = PETSC_TRUE;
2276     mat->assembled     = PETSC_FALSE;
2277   }
2278 #if defined(PETSC_USE_DEBUG)
2279   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2280   if (mat->rmap->mapping) {
2281     PetscInt irbs, rbs;
2282     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2283     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2284     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2285   }
2286   if (mat->cmap->mapping) {
2287     PetscInt icbs, cbs;
2288     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2289     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2290     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2291   }
2292 #endif
2293   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2294   if (mat->ops->setvaluesblockedlocal) {
2295     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2296   } else {
2297     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2298     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2299       irowm = buf; icolm = buf + nrow;
2300     } else {
2301       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2302       irowm = bufr; icolm = bufc;
2303     }
2304     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2305     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2306     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2307     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2308   }
2309   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2310   PetscFunctionReturn(0);
2311 }
2312 
2313 /*@
2314    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2315 
2316    Collective on Mat
2317 
2318    Input Parameters:
2319 +  mat - the matrix
2320 -  x   - the vector to be multiplied
2321 
2322    Output Parameters:
2323 .  y - the result
2324 
2325    Notes:
2326    The vectors x and y cannot be the same.  I.e., one cannot
2327    call MatMult(A,y,y).
2328 
2329    Level: developer
2330 
2331 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2332 @*/
2333 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2334 {
2335   PetscErrorCode ierr;
2336 
2337   PetscFunctionBegin;
2338   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2339   PetscValidType(mat,1);
2340   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2341   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2342 
2343   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2344   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2345   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2346   MatCheckPreallocated(mat,1);
2347 
2348   if (!mat->ops->multdiagonalblock) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2349   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2350   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2351   PetscFunctionReturn(0);
2352 }
2353 
2354 /* --------------------------------------------------------*/
2355 /*@
2356    MatMult - Computes the matrix-vector product, y = Ax.
2357 
2358    Neighbor-wise Collective on Mat
2359 
2360    Input Parameters:
2361 +  mat - the matrix
2362 -  x   - the vector to be multiplied
2363 
2364    Output Parameters:
2365 .  y - the result
2366 
2367    Notes:
2368    The vectors x and y cannot be the same.  I.e., one cannot
2369    call MatMult(A,y,y).
2370 
2371    Level: beginner
2372 
2373 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2374 @*/
2375 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2376 {
2377   PetscErrorCode ierr;
2378 
2379   PetscFunctionBegin;
2380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2381   PetscValidType(mat,1);
2382   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2383   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2385   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2386   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2387 #if !defined(PETSC_HAVE_CONSTRAINTS)
2388   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);
2389   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);
2390   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);
2391 #endif
2392   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2393   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2394   MatCheckPreallocated(mat,1);
2395 
2396   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2397   if (!mat->ops->mult) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2398   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2399   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2400   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2401   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2402   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2403   PetscFunctionReturn(0);
2404 }
2405 
2406 /*@
2407    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2408 
2409    Neighbor-wise Collective on Mat
2410 
2411    Input Parameters:
2412 +  mat - the matrix
2413 -  x   - the vector to be multiplied
2414 
2415    Output Parameters:
2416 .  y - the result
2417 
2418    Notes:
2419    The vectors x and y cannot be the same.  I.e., one cannot
2420    call MatMultTranspose(A,y,y).
2421 
2422    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2423    use MatMultHermitianTranspose()
2424 
2425    Level: beginner
2426 
2427 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2428 @*/
2429 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2430 {
2431   PetscErrorCode ierr;
2432 
2433   PetscFunctionBegin;
2434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2435   PetscValidType(mat,1);
2436   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2437   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2438 
2439   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2440   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2441   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2442 #if !defined(PETSC_HAVE_CONSTRAINTS)
2443   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);
2444   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);
2445 #endif
2446   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2447   MatCheckPreallocated(mat,1);
2448 
2449   if (!mat->ops->multtranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined",((PetscObject)mat)->type_name);
2450   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2451   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2452   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2453   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2454   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2455   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2456   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2457   PetscFunctionReturn(0);
2458 }
2459 
2460 /*@
2461    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2462 
2463    Neighbor-wise Collective on Mat
2464 
2465    Input Parameters:
2466 +  mat - the matrix
2467 -  x   - the vector to be multilplied
2468 
2469    Output Parameters:
2470 .  y - the result
2471 
2472    Notes:
2473    The vectors x and y cannot be the same.  I.e., one cannot
2474    call MatMultHermitianTranspose(A,y,y).
2475 
2476    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2477 
2478    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2479 
2480    Level: beginner
2481 
2482 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2483 @*/
2484 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2485 {
2486   PetscErrorCode ierr;
2487   Vec            w;
2488 
2489   PetscFunctionBegin;
2490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2491   PetscValidType(mat,1);
2492   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2493   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2494 
2495   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2496   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2497   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2498 #if !defined(PETSC_HAVE_CONSTRAINTS)
2499   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);
2500   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);
2501 #endif
2502   MatCheckPreallocated(mat,1);
2503 
2504   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2505   if (mat->ops->multhermitiantranspose) {
2506     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2507     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2508     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2509   } else {
2510     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2511     ierr = VecCopy(x,w);CHKERRQ(ierr);
2512     ierr = VecConjugate(w);CHKERRQ(ierr);
2513     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2514     ierr = VecDestroy(&w);CHKERRQ(ierr);
2515     ierr = VecConjugate(y);CHKERRQ(ierr);
2516   }
2517   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2518   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2519   PetscFunctionReturn(0);
2520 }
2521 
2522 /*@
2523     MatMultAdd -  Computes v3 = v2 + A * v1.
2524 
2525     Neighbor-wise Collective on Mat
2526 
2527     Input Parameters:
2528 +   mat - the matrix
2529 -   v1, v2 - the vectors
2530 
2531     Output Parameters:
2532 .   v3 - the result
2533 
2534     Notes:
2535     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2536     call MatMultAdd(A,v1,v2,v1).
2537 
2538     Level: beginner
2539 
2540 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2541 @*/
2542 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2543 {
2544   PetscErrorCode ierr;
2545 
2546   PetscFunctionBegin;
2547   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2548   PetscValidType(mat,1);
2549   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2550   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2551   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2552 
2553   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2554   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2555   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);
2556   /* 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);
2557      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); */
2558   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);
2559   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);
2560   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2561   MatCheckPreallocated(mat,1);
2562 
2563   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name);
2564   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2565   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2566   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2567   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2568   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2569   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2570   PetscFunctionReturn(0);
2571 }
2572 
2573 /*@
2574    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2575 
2576    Neighbor-wise Collective on Mat
2577 
2578    Input Parameters:
2579 +  mat - the matrix
2580 -  v1, v2 - the vectors
2581 
2582    Output Parameters:
2583 .  v3 - the result
2584 
2585    Notes:
2586    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2587    call MatMultTransposeAdd(A,v1,v2,v1).
2588 
2589    Level: beginner
2590 
2591 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2592 @*/
2593 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2594 {
2595   PetscErrorCode ierr;
2596 
2597   PetscFunctionBegin;
2598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2599   PetscValidType(mat,1);
2600   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2601   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2602   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2603 
2604   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2605   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2606   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2607   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2608   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);
2609   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);
2610   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);
2611   MatCheckPreallocated(mat,1);
2612 
2613   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2614   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2615   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2616   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2617   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2618   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2619   PetscFunctionReturn(0);
2620 }
2621 
2622 /*@
2623    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2624 
2625    Neighbor-wise Collective on Mat
2626 
2627    Input Parameters:
2628 +  mat - the matrix
2629 -  v1, v2 - the vectors
2630 
2631    Output Parameters:
2632 .  v3 - the result
2633 
2634    Notes:
2635    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2636    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2637 
2638    Level: beginner
2639 
2640 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2641 @*/
2642 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2643 {
2644   PetscErrorCode ierr;
2645 
2646   PetscFunctionBegin;
2647   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2648   PetscValidType(mat,1);
2649   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2650   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2651   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2652 
2653   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2654   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2655   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2656   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);
2657   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);
2658   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);
2659   MatCheckPreallocated(mat,1);
2660 
2661   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2662   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2663   if (mat->ops->multhermitiantransposeadd) {
2664     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2665   } else {
2666     Vec w,z;
2667     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2668     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2669     ierr = VecConjugate(w);CHKERRQ(ierr);
2670     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2671     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2672     ierr = VecDestroy(&w);CHKERRQ(ierr);
2673     ierr = VecConjugate(z);CHKERRQ(ierr);
2674     if (v2 != v3) {
2675       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2676     } else {
2677       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2678     }
2679     ierr = VecDestroy(&z);CHKERRQ(ierr);
2680   }
2681   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2682   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2683   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2684   PetscFunctionReturn(0);
2685 }
2686 
2687 /*@
2688    MatMultConstrained - The inner multiplication routine for a
2689    constrained matrix P^T A P.
2690 
2691    Neighbor-wise Collective on Mat
2692 
2693    Input Parameters:
2694 +  mat - the matrix
2695 -  x   - the vector to be multilplied
2696 
2697    Output Parameters:
2698 .  y - the result
2699 
2700    Notes:
2701    The vectors x and y cannot be the same.  I.e., one cannot
2702    call MatMult(A,y,y).
2703 
2704    Level: beginner
2705 
2706 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2707 @*/
2708 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2709 {
2710   PetscErrorCode ierr;
2711 
2712   PetscFunctionBegin;
2713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2714   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2715   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2716   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2717   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2718   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2719   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);
2720   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);
2721   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);
2722 
2723   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2724   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2725   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2726   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2727   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2728   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 /*@
2733    MatMultTransposeConstrained - The inner multiplication routine for a
2734    constrained matrix P^T A^T P.
2735 
2736    Neighbor-wise Collective on Mat
2737 
2738    Input Parameters:
2739 +  mat - the matrix
2740 -  x   - the vector to be multilplied
2741 
2742    Output Parameters:
2743 .  y - the result
2744 
2745    Notes:
2746    The vectors x and y cannot be the same.  I.e., one cannot
2747    call MatMult(A,y,y).
2748 
2749    Level: beginner
2750 
2751 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2752 @*/
2753 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2754 {
2755   PetscErrorCode ierr;
2756 
2757   PetscFunctionBegin;
2758   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2759   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2760   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2761   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2762   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2763   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2764   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2765   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2766 
2767   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2768   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2769   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2770   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2771   PetscFunctionReturn(0);
2772 }
2773 
2774 /*@C
2775    MatGetFactorType - gets the type of factorization it is
2776 
2777    Not Collective
2778 
2779    Input Parameters:
2780 .  mat - the matrix
2781 
2782    Output Parameters:
2783 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2784 
2785    Level: intermediate
2786 
2787 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2788 @*/
2789 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2790 {
2791   PetscFunctionBegin;
2792   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2793   PetscValidType(mat,1);
2794   PetscValidPointer(t,2);
2795   *t = mat->factortype;
2796   PetscFunctionReturn(0);
2797 }
2798 
2799 /*@C
2800    MatSetFactorType - sets the type of factorization it is
2801 
2802    Logically Collective on Mat
2803 
2804    Input Parameters:
2805 +  mat - the matrix
2806 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2807 
2808    Level: intermediate
2809 
2810 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2811 @*/
2812 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2813 {
2814   PetscFunctionBegin;
2815   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2816   PetscValidType(mat,1);
2817   mat->factortype = t;
2818   PetscFunctionReturn(0);
2819 }
2820 
2821 /* ------------------------------------------------------------*/
2822 /*@C
2823    MatGetInfo - Returns information about matrix storage (number of
2824    nonzeros, memory, etc.).
2825 
2826    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2827 
2828    Input Parameters:
2829 .  mat - the matrix
2830 
2831    Output Parameters:
2832 +  flag - flag indicating the type of parameters to be returned
2833    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2834    MAT_GLOBAL_SUM - sum over all processors)
2835 -  info - matrix information context
2836 
2837    Notes:
2838    The MatInfo context contains a variety of matrix data, including
2839    number of nonzeros allocated and used, number of mallocs during
2840    matrix assembly, etc.  Additional information for factored matrices
2841    is provided (such as the fill ratio, number of mallocs during
2842    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2843    when using the runtime options
2844 $       -info -mat_view ::ascii_info
2845 
2846    Example for C/C++ Users:
2847    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2848    data within the MatInfo context.  For example,
2849 .vb
2850       MatInfo info;
2851       Mat     A;
2852       double  mal, nz_a, nz_u;
2853 
2854       MatGetInfo(A,MAT_LOCAL,&info);
2855       mal  = info.mallocs;
2856       nz_a = info.nz_allocated;
2857 .ve
2858 
2859    Example for Fortran Users:
2860    Fortran users should declare info as a double precision
2861    array of dimension MAT_INFO_SIZE, and then extract the parameters
2862    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2863    a complete list of parameter names.
2864 .vb
2865       double  precision info(MAT_INFO_SIZE)
2866       double  precision mal, nz_a
2867       Mat     A
2868       integer ierr
2869 
2870       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2871       mal = info(MAT_INFO_MALLOCS)
2872       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2873 .ve
2874 
2875     Level: intermediate
2876 
2877     Developer Note: fortran interface is not autogenerated as the f90
2878     interface defintion cannot be generated correctly [due to MatInfo]
2879 
2880 .seealso: MatStashGetInfo()
2881 
2882 @*/
2883 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2884 {
2885   PetscErrorCode ierr;
2886 
2887   PetscFunctionBegin;
2888   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2889   PetscValidType(mat,1);
2890   PetscValidPointer(info,3);
2891   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2892   MatCheckPreallocated(mat,1);
2893   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2894   PetscFunctionReturn(0);
2895 }
2896 
2897 /*
2898    This is used by external packages where it is not easy to get the info from the actual
2899    matrix factorization.
2900 */
2901 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2902 {
2903   PetscErrorCode ierr;
2904 
2905   PetscFunctionBegin;
2906   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2907   PetscFunctionReturn(0);
2908 }
2909 
2910 /* ----------------------------------------------------------*/
2911 
2912 /*@C
2913    MatLUFactor - Performs in-place LU factorization of matrix.
2914 
2915    Collective on Mat
2916 
2917    Input Parameters:
2918 +  mat - the matrix
2919 .  row - row permutation
2920 .  col - column permutation
2921 -  info - options for factorization, includes
2922 $          fill - expected fill as ratio of original fill.
2923 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2924 $                   Run with the option -info to determine an optimal value to use
2925 
2926    Notes:
2927    Most users should employ the simplified KSP interface for linear solvers
2928    instead of working directly with matrix algebra routines such as this.
2929    See, e.g., KSPCreate().
2930 
2931    This changes the state of the matrix to a factored matrix; it cannot be used
2932    for example with MatSetValues() unless one first calls MatSetUnfactored().
2933 
2934    Level: developer
2935 
2936 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2937           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2938 
2939     Developer Note: fortran interface is not autogenerated as the f90
2940     interface defintion cannot be generated correctly [due to MatFactorInfo]
2941 
2942 @*/
2943 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2944 {
2945   PetscErrorCode ierr;
2946   MatFactorInfo  tinfo;
2947 
2948   PetscFunctionBegin;
2949   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2950   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2951   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2952   if (info) PetscValidPointer(info,4);
2953   PetscValidType(mat,1);
2954   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2955   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2956   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2957   MatCheckPreallocated(mat,1);
2958   if (!info) {
2959     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2960     info = &tinfo;
2961   }
2962 
2963   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2964   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2965   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2966   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2967   PetscFunctionReturn(0);
2968 }
2969 
2970 /*@C
2971    MatILUFactor - Performs in-place ILU factorization of matrix.
2972 
2973    Collective on Mat
2974 
2975    Input Parameters:
2976 +  mat - the matrix
2977 .  row - row permutation
2978 .  col - column permutation
2979 -  info - structure containing
2980 $      levels - number of levels of fill.
2981 $      expected fill - as ratio of original fill.
2982 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2983                 missing diagonal entries)
2984 
2985    Notes:
2986    Probably really in-place only when level of fill is zero, otherwise allocates
2987    new space to store factored matrix and deletes previous memory.
2988 
2989    Most users should employ the simplified KSP interface for linear solvers
2990    instead of working directly with matrix algebra routines such as this.
2991    See, e.g., KSPCreate().
2992 
2993    Level: developer
2994 
2995 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2996 
2997     Developer Note: fortran interface is not autogenerated as the f90
2998     interface defintion cannot be generated correctly [due to MatFactorInfo]
2999 
3000 @*/
3001 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3002 {
3003   PetscErrorCode ierr;
3004 
3005   PetscFunctionBegin;
3006   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3007   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3008   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3009   PetscValidPointer(info,4);
3010   PetscValidType(mat,1);
3011   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3012   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3013   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3014   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3015   MatCheckPreallocated(mat,1);
3016 
3017   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3018   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3019   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3020   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3021   PetscFunctionReturn(0);
3022 }
3023 
3024 /*@C
3025    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3026    Call this routine before calling MatLUFactorNumeric().
3027 
3028    Collective on Mat
3029 
3030    Input Parameters:
3031 +  fact - the factor matrix obtained with MatGetFactor()
3032 .  mat - the matrix
3033 .  row, col - row and column permutations
3034 -  info - options for factorization, includes
3035 $          fill - expected fill as ratio of original fill.
3036 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3037 $                   Run with the option -info to determine an optimal value to use
3038 
3039 
3040    Notes:
3041     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3042 
3043    Most users should employ the simplified KSP interface for linear solvers
3044    instead of working directly with matrix algebra routines such as this.
3045    See, e.g., KSPCreate().
3046 
3047    Level: developer
3048 
3049 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3050 
3051     Developer Note: fortran interface is not autogenerated as the f90
3052     interface defintion cannot be generated correctly [due to MatFactorInfo]
3053 
3054 @*/
3055 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3056 {
3057   PetscErrorCode ierr;
3058   MatFactorInfo  tinfo;
3059 
3060   PetscFunctionBegin;
3061   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3062   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3063   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3064   if (info) PetscValidPointer(info,4);
3065   PetscValidType(mat,1);
3066   PetscValidPointer(fact,5);
3067   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3068   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3069   if (!(fact)->ops->lufactorsymbolic) {
3070     MatSolverType spackage;
3071     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3072     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3073   }
3074   MatCheckPreallocated(mat,2);
3075   if (!info) {
3076     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3077     info = &tinfo;
3078   }
3079 
3080   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3081   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3082   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3083   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3084   PetscFunctionReturn(0);
3085 }
3086 
3087 /*@C
3088    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3089    Call this routine after first calling MatLUFactorSymbolic().
3090 
3091    Collective on Mat
3092 
3093    Input Parameters:
3094 +  fact - the factor matrix obtained with MatGetFactor()
3095 .  mat - the matrix
3096 -  info - options for factorization
3097 
3098    Notes:
3099    See MatLUFactor() for in-place factorization.  See
3100    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3101 
3102    Most users should employ the simplified KSP interface for linear solvers
3103    instead of working directly with matrix algebra routines such as this.
3104    See, e.g., KSPCreate().
3105 
3106    Level: developer
3107 
3108 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3109 
3110     Developer Note: fortran interface is not autogenerated as the f90
3111     interface defintion cannot be generated correctly [due to MatFactorInfo]
3112 
3113 @*/
3114 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3115 {
3116   MatFactorInfo  tinfo;
3117   PetscErrorCode ierr;
3118 
3119   PetscFunctionBegin;
3120   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3121   PetscValidType(mat,1);
3122   PetscValidPointer(fact,2);
3123   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3124   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3125   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);
3126 
3127   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3128   MatCheckPreallocated(mat,2);
3129   if (!info) {
3130     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3131     info = &tinfo;
3132   }
3133 
3134   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3135   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3136   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3137   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3138   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3139   PetscFunctionReturn(0);
3140 }
3141 
3142 /*@C
3143    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3144    symmetric matrix.
3145 
3146    Collective on Mat
3147 
3148    Input Parameters:
3149 +  mat - the matrix
3150 .  perm - row and column permutations
3151 -  f - expected fill as ratio of original fill
3152 
3153    Notes:
3154    See MatLUFactor() for the nonsymmetric case.  See also
3155    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3156 
3157    Most users should employ the simplified KSP interface for linear solvers
3158    instead of working directly with matrix algebra routines such as this.
3159    See, e.g., KSPCreate().
3160 
3161    Level: developer
3162 
3163 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3164           MatGetOrdering()
3165 
3166     Developer Note: fortran interface is not autogenerated as the f90
3167     interface defintion cannot be generated correctly [due to MatFactorInfo]
3168 
3169 @*/
3170 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3171 {
3172   PetscErrorCode ierr;
3173   MatFactorInfo  tinfo;
3174 
3175   PetscFunctionBegin;
3176   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3177   PetscValidType(mat,1);
3178   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3179   if (info) PetscValidPointer(info,3);
3180   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3181   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3182   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3183   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3184   MatCheckPreallocated(mat,1);
3185   if (!info) {
3186     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3187     info = &tinfo;
3188   }
3189 
3190   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3191   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3192   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3193   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3194   PetscFunctionReturn(0);
3195 }
3196 
3197 /*@C
3198    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3199    of a symmetric matrix.
3200 
3201    Collective on Mat
3202 
3203    Input Parameters:
3204 +  fact - the factor matrix obtained with MatGetFactor()
3205 .  mat - the matrix
3206 .  perm - row and column permutations
3207 -  info - options for factorization, includes
3208 $          fill - expected fill as ratio of original fill.
3209 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3210 $                   Run with the option -info to determine an optimal value to use
3211 
3212    Notes:
3213    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3214    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3215 
3216    Most users should employ the simplified KSP interface for linear solvers
3217    instead of working directly with matrix algebra routines such as this.
3218    See, e.g., KSPCreate().
3219 
3220    Level: developer
3221 
3222 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3223           MatGetOrdering()
3224 
3225     Developer Note: fortran interface is not autogenerated as the f90
3226     interface defintion cannot be generated correctly [due to MatFactorInfo]
3227 
3228 @*/
3229 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3230 {
3231   PetscErrorCode ierr;
3232   MatFactorInfo  tinfo;
3233 
3234   PetscFunctionBegin;
3235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3236   PetscValidType(mat,1);
3237   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3238   if (info) PetscValidPointer(info,3);
3239   PetscValidPointer(fact,4);
3240   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3241   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3242   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3243   if (!(fact)->ops->choleskyfactorsymbolic) {
3244     MatSolverType spackage;
3245     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3246     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3247   }
3248   MatCheckPreallocated(mat,2);
3249   if (!info) {
3250     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3251     info = &tinfo;
3252   }
3253 
3254   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3255   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3256   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3257   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3258   PetscFunctionReturn(0);
3259 }
3260 
3261 /*@C
3262    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3263    of a symmetric matrix. Call this routine after first calling
3264    MatCholeskyFactorSymbolic().
3265 
3266    Collective on Mat
3267 
3268    Input Parameters:
3269 +  fact - the factor matrix obtained with MatGetFactor()
3270 .  mat - the initial matrix
3271 .  info - options for factorization
3272 -  fact - the symbolic factor of mat
3273 
3274 
3275    Notes:
3276    Most users should employ the simplified KSP interface for linear solvers
3277    instead of working directly with matrix algebra routines such as this.
3278    See, e.g., KSPCreate().
3279 
3280    Level: developer
3281 
3282 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3283 
3284     Developer Note: fortran interface is not autogenerated as the f90
3285     interface defintion cannot be generated correctly [due to MatFactorInfo]
3286 
3287 @*/
3288 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3289 {
3290   MatFactorInfo  tinfo;
3291   PetscErrorCode ierr;
3292 
3293   PetscFunctionBegin;
3294   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3295   PetscValidType(mat,1);
3296   PetscValidPointer(fact,2);
3297   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3298   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3299   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3300   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);
3301   MatCheckPreallocated(mat,2);
3302   if (!info) {
3303     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3304     info = &tinfo;
3305   }
3306 
3307   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3308   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3309   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3310   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3311   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3312   PetscFunctionReturn(0);
3313 }
3314 
3315 /* ----------------------------------------------------------------*/
3316 /*@
3317    MatSolve - Solves A x = b, given a factored matrix.
3318 
3319    Neighbor-wise Collective on Mat
3320 
3321    Input Parameters:
3322 +  mat - the factored matrix
3323 -  b - the right-hand-side vector
3324 
3325    Output Parameter:
3326 .  x - the result vector
3327 
3328    Notes:
3329    The vectors b and x cannot be the same.  I.e., one cannot
3330    call MatSolve(A,x,x).
3331 
3332    Notes:
3333    Most users should employ the simplified KSP interface for linear solvers
3334    instead of working directly with matrix algebra routines such as this.
3335    See, e.g., KSPCreate().
3336 
3337    Level: developer
3338 
3339 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3340 @*/
3341 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3342 {
3343   PetscErrorCode ierr;
3344 
3345   PetscFunctionBegin;
3346   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3347   PetscValidType(mat,1);
3348   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3349   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3350   PetscCheckSameComm(mat,1,b,2);
3351   PetscCheckSameComm(mat,1,x,3);
3352   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3353   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);
3354   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);
3355   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);
3356   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3357   MatCheckPreallocated(mat,1);
3358 
3359   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3360   if (mat->factorerrortype) {
3361     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3362     ierr = VecSetInf(x);CHKERRQ(ierr);
3363   } else {
3364     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3365     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3366   }
3367   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3368   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3369   PetscFunctionReturn(0);
3370 }
3371 
3372 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3373 {
3374   PetscErrorCode ierr;
3375   Vec            b,x;
3376   PetscInt       m,N,i;
3377   PetscScalar    *bb,*xx;
3378 
3379   PetscFunctionBegin;
3380   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3381   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3382   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3383   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3384   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3385   for (i=0; i<N; i++) {
3386     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3387     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3388     if (trans) {
3389       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3390     } else {
3391       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3392     }
3393     ierr = VecResetArray(x);CHKERRQ(ierr);
3394     ierr = VecResetArray(b);CHKERRQ(ierr);
3395   }
3396   ierr = VecDestroy(&b);CHKERRQ(ierr);
3397   ierr = VecDestroy(&x);CHKERRQ(ierr);
3398   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3399   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3400   PetscFunctionReturn(0);
3401 }
3402 
3403 /*@
3404    MatMatSolve - Solves A X = B, given a factored matrix.
3405 
3406    Neighbor-wise Collective on Mat
3407 
3408    Input Parameters:
3409 +  A - the factored matrix
3410 -  B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3411 
3412    Output Parameter:
3413 .  X - the result matrix (dense matrix)
3414 
3415    Notes:
3416    If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B);
3417    otherwise, B and X cannot be the same.
3418 
3419    Notes:
3420    Most users should usually employ the simplified KSP interface for linear solvers
3421    instead of working directly with matrix algebra routines such as this.
3422    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3423    at a time.
3424 
3425    Level: developer
3426 
3427 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3428 @*/
3429 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3430 {
3431   PetscErrorCode ierr;
3432 
3433   PetscFunctionBegin;
3434   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3435   PetscValidType(A,1);
3436   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3437   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3438   PetscCheckSameComm(A,1,B,2);
3439   PetscCheckSameComm(A,1,X,3);
3440   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);
3441   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);
3442   if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),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->matsolve) {
3449     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3450     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3451   } else {
3452     ierr = (*A->ops->matsolve)(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    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3461 
3462    Neighbor-wise Collective on Mat
3463 
3464    Input Parameters:
3465 +  A - the factored matrix
3466 -  B - the right-hand-side matrix  (dense matrix)
3467 
3468    Output Parameter:
3469 .  X - the result matrix (dense matrix)
3470 
3471    Notes:
3472    The matrices B and X cannot be the same.  I.e., one cannot
3473    call MatMatSolveTranspose(A,X,X).
3474 
3475    Notes:
3476    Most users should usually employ the simplified KSP interface for linear solvers
3477    instead of working directly with matrix algebra routines such as this.
3478    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3479    at a time.
3480 
3481    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3482 
3483    Level: developer
3484 
3485 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3486 @*/
3487 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3488 {
3489   PetscErrorCode ierr;
3490 
3491   PetscFunctionBegin;
3492   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3493   PetscValidType(A,1);
3494   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3495   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3496   PetscCheckSameComm(A,1,B,2);
3497   PetscCheckSameComm(A,1,X,3);
3498   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3499   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);
3500   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);
3501   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);
3502   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");
3503   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3504   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3505   MatCheckPreallocated(A,1);
3506 
3507   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3508   if (!A->ops->matsolvetranspose) {
3509     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3510     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3511   } else {
3512     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3513   }
3514   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3515   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3516   PetscFunctionReturn(0);
3517 }
3518 
3519 /*@
3520    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3521 
3522    Neighbor-wise Collective on Mat
3523 
3524    Input Parameters:
3525 +  A - the factored matrix
3526 -  Bt - the transpose of right-hand-side matrix
3527 
3528    Output Parameter:
3529 .  X - the result matrix (dense matrix)
3530 
3531    Notes:
3532    Most users should usually employ the simplified KSP interface for linear solvers
3533    instead of working directly with matrix algebra routines such as this.
3534    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3535    at a time.
3536 
3537    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().
3538 
3539    Level: developer
3540 
3541 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3542 @*/
3543 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3544 {
3545   PetscErrorCode ierr;
3546 
3547   PetscFunctionBegin;
3548   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3549   PetscValidType(A,1);
3550   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3551   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3552   PetscCheckSameComm(A,1,Bt,2);
3553   PetscCheckSameComm(A,1,X,3);
3554 
3555   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3556   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);
3557   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);
3558   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");
3559   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3560   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3561   MatCheckPreallocated(A,1);
3562 
3563   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3564   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3565   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3566   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3567   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3568   PetscFunctionReturn(0);
3569 }
3570 
3571 /*@
3572    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3573                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3574 
3575    Neighbor-wise Collective on Mat
3576 
3577    Input Parameters:
3578 +  mat - the factored matrix
3579 -  b - the right-hand-side vector
3580 
3581    Output Parameter:
3582 .  x - the result vector
3583 
3584    Notes:
3585    MatSolve() should be used for most applications, as it performs
3586    a forward solve followed by a backward solve.
3587 
3588    The vectors b and x cannot be the same,  i.e., one cannot
3589    call MatForwardSolve(A,x,x).
3590 
3591    For matrix in seqsbaij format with block size larger than 1,
3592    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3593    MatForwardSolve() solves U^T*D y = b, and
3594    MatBackwardSolve() solves U x = y.
3595    Thus they do not provide a symmetric preconditioner.
3596 
3597    Most users should employ the simplified KSP interface for linear solvers
3598    instead of working directly with matrix algebra routines such as this.
3599    See, e.g., KSPCreate().
3600 
3601    Level: developer
3602 
3603 .seealso: MatSolve(), MatBackwardSolve()
3604 @*/
3605 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3606 {
3607   PetscErrorCode ierr;
3608 
3609   PetscFunctionBegin;
3610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3611   PetscValidType(mat,1);
3612   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3613   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3614   PetscCheckSameComm(mat,1,b,2);
3615   PetscCheckSameComm(mat,1,x,3);
3616   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3617   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);
3618   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);
3619   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);
3620   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3621   MatCheckPreallocated(mat,1);
3622 
3623   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3624   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3625   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3626   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3627   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3628   PetscFunctionReturn(0);
3629 }
3630 
3631 /*@
3632    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3633                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3634 
3635    Neighbor-wise Collective on Mat
3636 
3637    Input Parameters:
3638 +  mat - the factored matrix
3639 -  b - the right-hand-side vector
3640 
3641    Output Parameter:
3642 .  x - the result vector
3643 
3644    Notes:
3645    MatSolve() should be used for most applications, as it performs
3646    a forward solve followed by a backward solve.
3647 
3648    The vectors b and x cannot be the same.  I.e., one cannot
3649    call MatBackwardSolve(A,x,x).
3650 
3651    For matrix in seqsbaij format with block size larger than 1,
3652    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3653    MatForwardSolve() solves U^T*D y = b, and
3654    MatBackwardSolve() solves U x = y.
3655    Thus they do not provide a symmetric preconditioner.
3656 
3657    Most users should employ the simplified KSP interface for linear solvers
3658    instead of working directly with matrix algebra routines such as this.
3659    See, e.g., KSPCreate().
3660 
3661    Level: developer
3662 
3663 .seealso: MatSolve(), MatForwardSolve()
3664 @*/
3665 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3666 {
3667   PetscErrorCode ierr;
3668 
3669   PetscFunctionBegin;
3670   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3671   PetscValidType(mat,1);
3672   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3673   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3674   PetscCheckSameComm(mat,1,b,2);
3675   PetscCheckSameComm(mat,1,x,3);
3676   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3677   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);
3678   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);
3679   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);
3680   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3681   MatCheckPreallocated(mat,1);
3682 
3683   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3684   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3685   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3686   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3687   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3688   PetscFunctionReturn(0);
3689 }
3690 
3691 /*@
3692    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3693 
3694    Neighbor-wise Collective on Mat
3695 
3696    Input Parameters:
3697 +  mat - the factored matrix
3698 .  b - the right-hand-side vector
3699 -  y - the vector to be added to
3700 
3701    Output Parameter:
3702 .  x - the result vector
3703 
3704    Notes:
3705    The vectors b and x cannot be the same.  I.e., one cannot
3706    call MatSolveAdd(A,x,y,x).
3707 
3708    Most users should employ the simplified KSP interface for linear solvers
3709    instead of working directly with matrix algebra routines such as this.
3710    See, e.g., KSPCreate().
3711 
3712    Level: developer
3713 
3714 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3715 @*/
3716 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3717 {
3718   PetscScalar    one = 1.0;
3719   Vec            tmp;
3720   PetscErrorCode ierr;
3721 
3722   PetscFunctionBegin;
3723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3724   PetscValidType(mat,1);
3725   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3726   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3727   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3728   PetscCheckSameComm(mat,1,b,2);
3729   PetscCheckSameComm(mat,1,y,2);
3730   PetscCheckSameComm(mat,1,x,3);
3731   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3732   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);
3733   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);
3734   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);
3735   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);
3736   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);
3737   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3738    MatCheckPreallocated(mat,1);
3739 
3740   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3741   if (mat->factorerrortype) {
3742     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3743     ierr = VecSetInf(x);CHKERRQ(ierr);
3744   } else if (mat->ops->solveadd) {
3745     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3746   } else {
3747     /* do the solve then the add manually */
3748     if (x != y) {
3749       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3750       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3751     } else {
3752       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3753       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3754       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3755       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3756       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3757       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3758     }
3759   }
3760   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3761   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3762   PetscFunctionReturn(0);
3763 }
3764 
3765 /*@
3766    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3767 
3768    Neighbor-wise Collective on Mat
3769 
3770    Input Parameters:
3771 +  mat - the factored matrix
3772 -  b - the right-hand-side vector
3773 
3774    Output Parameter:
3775 .  x - the result vector
3776 
3777    Notes:
3778    The vectors b and x cannot be the same.  I.e., one cannot
3779    call MatSolveTranspose(A,x,x).
3780 
3781    Most users should employ the simplified KSP interface for linear solvers
3782    instead of working directly with matrix algebra routines such as this.
3783    See, e.g., KSPCreate().
3784 
3785    Level: developer
3786 
3787 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3788 @*/
3789 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3790 {
3791   PetscErrorCode ierr;
3792 
3793   PetscFunctionBegin;
3794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3795   PetscValidType(mat,1);
3796   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3797   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3798   PetscCheckSameComm(mat,1,b,2);
3799   PetscCheckSameComm(mat,1,x,3);
3800   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3801   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);
3802   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);
3803   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3804   MatCheckPreallocated(mat,1);
3805   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3806   if (mat->factorerrortype) {
3807     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3808     ierr = VecSetInf(x);CHKERRQ(ierr);
3809   } else {
3810     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3811     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3812   }
3813   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3814   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3815   PetscFunctionReturn(0);
3816 }
3817 
3818 /*@
3819    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3820                       factored matrix.
3821 
3822    Neighbor-wise Collective on Mat
3823 
3824    Input Parameters:
3825 +  mat - the factored matrix
3826 .  b - the right-hand-side vector
3827 -  y - the vector to be added to
3828 
3829    Output Parameter:
3830 .  x - the result vector
3831 
3832    Notes:
3833    The vectors b and x cannot be the same.  I.e., one cannot
3834    call MatSolveTransposeAdd(A,x,y,x).
3835 
3836    Most users should employ the simplified KSP interface for linear solvers
3837    instead of working directly with matrix algebra routines such as this.
3838    See, e.g., KSPCreate().
3839 
3840    Level: developer
3841 
3842 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3843 @*/
3844 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3845 {
3846   PetscScalar    one = 1.0;
3847   PetscErrorCode ierr;
3848   Vec            tmp;
3849 
3850   PetscFunctionBegin;
3851   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3852   PetscValidType(mat,1);
3853   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3854   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3855   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3856   PetscCheckSameComm(mat,1,b,2);
3857   PetscCheckSameComm(mat,1,y,3);
3858   PetscCheckSameComm(mat,1,x,4);
3859   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3860   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);
3861   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);
3862   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);
3863   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);
3864   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3865    MatCheckPreallocated(mat,1);
3866 
3867   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3868   if (mat->factorerrortype) {
3869     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3870     ierr = VecSetInf(x);CHKERRQ(ierr);
3871   } else if (mat->ops->solvetransposeadd){
3872     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3873   } else {
3874     /* do the solve then the add manually */
3875     if (x != y) {
3876       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3877       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3878     } else {
3879       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3880       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3881       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3882       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3883       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3884       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3885     }
3886   }
3887   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3888   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3889   PetscFunctionReturn(0);
3890 }
3891 /* ----------------------------------------------------------------*/
3892 
3893 /*@
3894    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3895 
3896    Neighbor-wise Collective on Mat
3897 
3898    Input Parameters:
3899 +  mat - the matrix
3900 .  b - the right hand side
3901 .  omega - the relaxation factor
3902 .  flag - flag indicating the type of SOR (see below)
3903 .  shift -  diagonal shift
3904 .  its - the number of iterations
3905 -  lits - the number of local iterations
3906 
3907    Output Parameters:
3908 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3909 
3910    SOR Flags:
3911 +     SOR_FORWARD_SWEEP - forward SOR
3912 .     SOR_BACKWARD_SWEEP - backward SOR
3913 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3914 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3915 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3916 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3917 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3918          upper/lower triangular part of matrix to
3919          vector (with omega)
3920 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
3921 
3922    Notes:
3923    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3924    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3925    on each processor.
3926 
3927    Application programmers will not generally use MatSOR() directly,
3928    but instead will employ the KSP/PC interface.
3929 
3930    Notes:
3931     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3932 
3933    Notes for Advanced Users:
3934    The flags are implemented as bitwise inclusive or operations.
3935    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3936    to specify a zero initial guess for SSOR.
3937 
3938    Most users should employ the simplified KSP interface for linear solvers
3939    instead of working directly with matrix algebra routines such as this.
3940    See, e.g., KSPCreate().
3941 
3942    Vectors x and b CANNOT be the same
3943 
3944    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3945 
3946    Level: developer
3947 
3948 @*/
3949 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3950 {
3951   PetscErrorCode ierr;
3952 
3953   PetscFunctionBegin;
3954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3955   PetscValidType(mat,1);
3956   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3957   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3958   PetscCheckSameComm(mat,1,b,2);
3959   PetscCheckSameComm(mat,1,x,8);
3960   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3961   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3962   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3963   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);
3964   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);
3965   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);
3966   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3967   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3968   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3969 
3970   MatCheckPreallocated(mat,1);
3971   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3972   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3973   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3974   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3975   PetscFunctionReturn(0);
3976 }
3977 
3978 /*
3979       Default matrix copy routine.
3980 */
3981 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3982 {
3983   PetscErrorCode    ierr;
3984   PetscInt          i,rstart = 0,rend = 0,nz;
3985   const PetscInt    *cwork;
3986   const PetscScalar *vwork;
3987 
3988   PetscFunctionBegin;
3989   if (B->assembled) {
3990     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3991   }
3992   if (str == SAME_NONZERO_PATTERN) {
3993     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3994     for (i=rstart; i<rend; i++) {
3995       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3996       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3997       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3998     }
3999   } else {
4000     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4001   }
4002   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4003   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4004   PetscFunctionReturn(0);
4005 }
4006 
4007 /*@
4008    MatCopy - Copies a matrix to another matrix.
4009 
4010    Collective on Mat
4011 
4012    Input Parameters:
4013 +  A - the matrix
4014 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4015 
4016    Output Parameter:
4017 .  B - where the copy is put
4018 
4019    Notes:
4020    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4021    same nonzero pattern or the routine will crash.
4022 
4023    MatCopy() copies the matrix entries of a matrix to another existing
4024    matrix (after first zeroing the second matrix).  A related routine is
4025    MatConvert(), which first creates a new matrix and then copies the data.
4026 
4027    Level: intermediate
4028 
4029 .seealso: MatConvert(), MatDuplicate()
4030 
4031 @*/
4032 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4033 {
4034   PetscErrorCode ierr;
4035   PetscInt       i;
4036 
4037   PetscFunctionBegin;
4038   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4039   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4040   PetscValidType(A,1);
4041   PetscValidType(B,2);
4042   PetscCheckSameComm(A,1,B,2);
4043   MatCheckPreallocated(B,2);
4044   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4045   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4046   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);
4047   MatCheckPreallocated(A,1);
4048   if (A == B) PetscFunctionReturn(0);
4049 
4050   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4051   if (A->ops->copy) {
4052     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4053   } else { /* generic conversion */
4054     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4055   }
4056 
4057   B->stencil.dim = A->stencil.dim;
4058   B->stencil.noc = A->stencil.noc;
4059   for (i=0; i<=A->stencil.dim; i++) {
4060     B->stencil.dims[i]   = A->stencil.dims[i];
4061     B->stencil.starts[i] = A->stencil.starts[i];
4062   }
4063 
4064   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4065   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4066   PetscFunctionReturn(0);
4067 }
4068 
4069 /*@C
4070    MatConvert - Converts a matrix to another matrix, either of the same
4071    or different type.
4072 
4073    Collective on Mat
4074 
4075    Input Parameters:
4076 +  mat - the matrix
4077 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4078    same type as the original matrix.
4079 -  reuse - denotes if the destination matrix is to be created or reused.
4080    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
4081    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).
4082 
4083    Output Parameter:
4084 .  M - pointer to place new matrix
4085 
4086    Notes:
4087    MatConvert() first creates a new matrix and then copies the data from
4088    the first matrix.  A related routine is MatCopy(), which copies the matrix
4089    entries of one matrix to another already existing matrix context.
4090 
4091    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4092    the MPI communicator of the generated matrix is always the same as the communicator
4093    of the input matrix.
4094 
4095    Level: intermediate
4096 
4097 .seealso: MatCopy(), MatDuplicate()
4098 @*/
4099 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4100 {
4101   PetscErrorCode ierr;
4102   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4103   char           convname[256],mtype[256];
4104   Mat            B;
4105 
4106   PetscFunctionBegin;
4107   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4108   PetscValidType(mat,1);
4109   PetscValidPointer(M,3);
4110   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4111   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4112   MatCheckPreallocated(mat,1);
4113 
4114   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4115   if (flg) newtype = mtype;
4116 
4117   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4118   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4119   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4120   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");
4121 
4122   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4123     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4124     PetscFunctionReturn(0);
4125   }
4126 
4127   /* Cache Mat options because some converter use MatHeaderReplace  */
4128   issymmetric = mat->symmetric;
4129   ishermitian = mat->hermitian;
4130 
4131   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4132     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4133     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4134   } else {
4135     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4136     const char     *prefix[3] = {"seq","mpi",""};
4137     PetscInt       i;
4138     /*
4139        Order of precedence:
4140        0) See if newtype is a superclass of the current matrix.
4141        1) See if a specialized converter is known to the current matrix.
4142        2) See if a specialized converter is known to the desired matrix class.
4143        3) See if a good general converter is registered for the desired class
4144           (as of 6/27/03 only MATMPIADJ falls into this category).
4145        4) See if a good general converter is known for the current matrix.
4146        5) Use a really basic converter.
4147     */
4148 
4149     /* 0) See if newtype is a superclass of the current matrix.
4150           i.e mat is mpiaij and newtype is aij */
4151     for (i=0; i<2; i++) {
4152       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4153       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4154       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4155       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4156       if (flg) {
4157         if (reuse == MAT_INPLACE_MATRIX) {
4158           PetscFunctionReturn(0);
4159         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4160           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4161           PetscFunctionReturn(0);
4162         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4163           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4164           PetscFunctionReturn(0);
4165         }
4166       }
4167     }
4168     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4169     for (i=0; i<3; i++) {
4170       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4171       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4172       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4173       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4174       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4175       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4176       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4177       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4178       if (conv) goto foundconv;
4179     }
4180 
4181     /* 2)  See if a specialized converter is known to the desired matrix class. */
4182     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4183     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4184     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4185     for (i=0; i<3; i++) {
4186       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4187       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4188       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4189       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4190       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4191       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4192       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4193       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4194       if (conv) {
4195         ierr = MatDestroy(&B);CHKERRQ(ierr);
4196         goto foundconv;
4197       }
4198     }
4199 
4200     /* 3) See if a good general converter is registered for the desired class */
4201     conv = B->ops->convertfrom;
4202     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4203     ierr = MatDestroy(&B);CHKERRQ(ierr);
4204     if (conv) goto foundconv;
4205 
4206     /* 4) See if a good general converter is known for the current matrix */
4207     if (mat->ops->convert) conv = mat->ops->convert;
4208 
4209     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4210     if (conv) goto foundconv;
4211 
4212     /* 5) Use a really basic converter. */
4213     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4214     conv = MatConvert_Basic;
4215 
4216 foundconv:
4217     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4218     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4219     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4220       /* the block sizes must be same if the mappings are copied over */
4221       (*M)->rmap->bs = mat->rmap->bs;
4222       (*M)->cmap->bs = mat->cmap->bs;
4223       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4224       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4225       (*M)->rmap->mapping = mat->rmap->mapping;
4226       (*M)->cmap->mapping = mat->cmap->mapping;
4227     }
4228     (*M)->stencil.dim = mat->stencil.dim;
4229     (*M)->stencil.noc = mat->stencil.noc;
4230     for (i=0; i<=mat->stencil.dim; i++) {
4231       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4232       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4233     }
4234     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4235   }
4236   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4237 
4238   /* Copy Mat options */
4239   if (issymmetric) {
4240     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4241   }
4242   if (ishermitian) {
4243     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4244   }
4245   PetscFunctionReturn(0);
4246 }
4247 
4248 /*@C
4249    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4250 
4251    Not Collective
4252 
4253    Input Parameter:
4254 .  mat - the matrix, must be a factored matrix
4255 
4256    Output Parameter:
4257 .   type - the string name of the package (do not free this string)
4258 
4259    Notes:
4260       In Fortran you pass in a empty string and the package name will be copied into it.
4261     (Make sure the string is long enough)
4262 
4263    Level: intermediate
4264 
4265 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4266 @*/
4267 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4268 {
4269   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4270 
4271   PetscFunctionBegin;
4272   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4273   PetscValidType(mat,1);
4274   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4275   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4276   if (!conv) {
4277     *type = MATSOLVERPETSC;
4278   } else {
4279     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4280   }
4281   PetscFunctionReturn(0);
4282 }
4283 
4284 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4285 struct _MatSolverTypeForSpecifcType {
4286   MatType                        mtype;
4287   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4288   MatSolverTypeForSpecifcType next;
4289 };
4290 
4291 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4292 struct _MatSolverTypeHolder {
4293   char                           *name;
4294   MatSolverTypeForSpecifcType handlers;
4295   MatSolverTypeHolder         next;
4296 };
4297 
4298 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4299 
4300 /*@C
4301    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4302 
4303    Input Parameters:
4304 +    package - name of the package, for example petsc or superlu
4305 .    mtype - the matrix type that works with this package
4306 .    ftype - the type of factorization supported by the package
4307 -    getfactor - routine that will create the factored matrix ready to be used
4308 
4309     Level: intermediate
4310 
4311 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4312 @*/
4313 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4314 {
4315   PetscErrorCode              ierr;
4316   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4317   PetscBool                   flg;
4318   MatSolverTypeForSpecifcType inext,iprev = NULL;
4319 
4320   PetscFunctionBegin;
4321   ierr = MatInitializePackage();CHKERRQ(ierr);
4322   if (!next) {
4323     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4324     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4325     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4326     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4327     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4328     PetscFunctionReturn(0);
4329   }
4330   while (next) {
4331     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4332     if (flg) {
4333       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4334       inext = next->handlers;
4335       while (inext) {
4336         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4337         if (flg) {
4338           inext->getfactor[(int)ftype-1] = getfactor;
4339           PetscFunctionReturn(0);
4340         }
4341         iprev = inext;
4342         inext = inext->next;
4343       }
4344       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4345       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4346       iprev->next->getfactor[(int)ftype-1] = getfactor;
4347       PetscFunctionReturn(0);
4348     }
4349     prev = next;
4350     next = next->next;
4351   }
4352   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4353   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4354   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4355   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4356   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4357   PetscFunctionReturn(0);
4358 }
4359 
4360 /*@C
4361    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4362 
4363    Input Parameters:
4364 +    package - name of the package, for example petsc or superlu
4365 .    ftype - the type of factorization supported by the package
4366 -    mtype - the matrix type that works with this package
4367 
4368    Output Parameters:
4369 +   foundpackage - PETSC_TRUE if the package was registered
4370 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4371 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4372 
4373     Level: intermediate
4374 
4375 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4376 @*/
4377 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4378 {
4379   PetscErrorCode              ierr;
4380   MatSolverTypeHolder         next = MatSolverTypeHolders;
4381   PetscBool                   flg;
4382   MatSolverTypeForSpecifcType inext;
4383 
4384   PetscFunctionBegin;
4385   if (foundpackage) *foundpackage = PETSC_FALSE;
4386   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4387   if (getfactor)    *getfactor    = NULL;
4388 
4389   if (package) {
4390     while (next) {
4391       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4392       if (flg) {
4393         if (foundpackage) *foundpackage = PETSC_TRUE;
4394         inext = next->handlers;
4395         while (inext) {
4396           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4397           if (flg) {
4398             if (foundmtype) *foundmtype = PETSC_TRUE;
4399             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4400             PetscFunctionReturn(0);
4401           }
4402           inext = inext->next;
4403         }
4404       }
4405       next = next->next;
4406     }
4407   } else {
4408     while (next) {
4409       inext = next->handlers;
4410       while (inext) {
4411         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4412         if (flg && inext->getfactor[(int)ftype-1]) {
4413           if (foundpackage) *foundpackage = PETSC_TRUE;
4414           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4415           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4416           PetscFunctionReturn(0);
4417         }
4418         inext = inext->next;
4419       }
4420       next = next->next;
4421     }
4422   }
4423   PetscFunctionReturn(0);
4424 }
4425 
4426 PetscErrorCode MatSolverTypeDestroy(void)
4427 {
4428   PetscErrorCode              ierr;
4429   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4430   MatSolverTypeForSpecifcType inext,iprev;
4431 
4432   PetscFunctionBegin;
4433   while (next) {
4434     ierr = PetscFree(next->name);CHKERRQ(ierr);
4435     inext = next->handlers;
4436     while (inext) {
4437       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4438       iprev = inext;
4439       inext = inext->next;
4440       ierr = PetscFree(iprev);CHKERRQ(ierr);
4441     }
4442     prev = next;
4443     next = next->next;
4444     ierr = PetscFree(prev);CHKERRQ(ierr);
4445   }
4446   MatSolverTypeHolders = NULL;
4447   PetscFunctionReturn(0);
4448 }
4449 
4450 /*@C
4451    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4452 
4453    Collective on Mat
4454 
4455    Input Parameters:
4456 +  mat - the matrix
4457 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4458 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4459 
4460    Output Parameters:
4461 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4462 
4463    Notes:
4464       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4465      such as pastix, superlu, mumps etc.
4466 
4467       PETSc must have been ./configure to use the external solver, using the option --download-package
4468 
4469    Level: intermediate
4470 
4471 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4472 @*/
4473 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4474 {
4475   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4476   PetscBool      foundpackage,foundmtype;
4477 
4478   PetscFunctionBegin;
4479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4480   PetscValidType(mat,1);
4481 
4482   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4483   MatCheckPreallocated(mat,1);
4484 
4485   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4486   if (!foundpackage) {
4487     if (type) {
4488       SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type);
4489     } else {
4490       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4491     }
4492   }
4493   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4494   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);
4495 
4496   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4497   PetscFunctionReturn(0);
4498 }
4499 
4500 /*@C
4501    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4502 
4503    Not Collective
4504 
4505    Input Parameters:
4506 +  mat - the matrix
4507 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4508 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4509 
4510    Output Parameter:
4511 .    flg - PETSC_TRUE if the factorization is available
4512 
4513    Notes:
4514       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4515      such as pastix, superlu, mumps etc.
4516 
4517       PETSc must have been ./configure to use the external solver, using the option --download-package
4518 
4519    Level: intermediate
4520 
4521 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4522 @*/
4523 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4524 {
4525   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4526 
4527   PetscFunctionBegin;
4528   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4529   PetscValidType(mat,1);
4530 
4531   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4532   MatCheckPreallocated(mat,1);
4533 
4534   *flg = PETSC_FALSE;
4535   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4536   if (gconv) {
4537     *flg = PETSC_TRUE;
4538   }
4539   PetscFunctionReturn(0);
4540 }
4541 
4542 #include <petscdmtypes.h>
4543 
4544 /*@
4545    MatDuplicate - Duplicates a matrix including the non-zero structure.
4546 
4547    Collective on Mat
4548 
4549    Input Parameters:
4550 +  mat - the matrix
4551 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4552         See the manual page for MatDuplicateOption for an explanation of these options.
4553 
4554    Output Parameter:
4555 .  M - pointer to place new matrix
4556 
4557    Level: intermediate
4558 
4559    Notes:
4560     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4561     When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation.
4562 
4563 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4564 @*/
4565 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4566 {
4567   PetscErrorCode ierr;
4568   Mat            B;
4569   PetscInt       i;
4570   DM             dm;
4571   void           (*viewf)(void);
4572 
4573   PetscFunctionBegin;
4574   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4575   PetscValidType(mat,1);
4576   PetscValidPointer(M,3);
4577   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4578   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4579   MatCheckPreallocated(mat,1);
4580 
4581   *M = 0;
4582   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4583   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4584   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4585   B    = *M;
4586 
4587   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4588   if (viewf) {
4589     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4590   }
4591 
4592   B->stencil.dim = mat->stencil.dim;
4593   B->stencil.noc = mat->stencil.noc;
4594   for (i=0; i<=mat->stencil.dim; i++) {
4595     B->stencil.dims[i]   = mat->stencil.dims[i];
4596     B->stencil.starts[i] = mat->stencil.starts[i];
4597   }
4598 
4599   B->nooffproczerorows = mat->nooffproczerorows;
4600   B->nooffprocentries  = mat->nooffprocentries;
4601 
4602   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4603   if (dm) {
4604     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4605   }
4606   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4607   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4608   PetscFunctionReturn(0);
4609 }
4610 
4611 /*@
4612    MatGetDiagonal - Gets the diagonal of a matrix.
4613 
4614    Logically Collective on Mat
4615 
4616    Input Parameters:
4617 +  mat - the matrix
4618 -  v - the vector for storing the diagonal
4619 
4620    Output Parameter:
4621 .  v - the diagonal of the matrix
4622 
4623    Level: intermediate
4624 
4625    Note:
4626    Currently only correct in parallel for square matrices.
4627 
4628 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4629 @*/
4630 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4631 {
4632   PetscErrorCode ierr;
4633 
4634   PetscFunctionBegin;
4635   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4636   PetscValidType(mat,1);
4637   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4638   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4639   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4640   MatCheckPreallocated(mat,1);
4641 
4642   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4643   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4644   PetscFunctionReturn(0);
4645 }
4646 
4647 /*@C
4648    MatGetRowMin - Gets the minimum value (of the real part) of each
4649         row of the matrix
4650 
4651    Logically Collective on Mat
4652 
4653    Input Parameters:
4654 .  mat - the matrix
4655 
4656    Output Parameter:
4657 +  v - the vector for storing the maximums
4658 -  idx - the indices of the column found for each row (optional)
4659 
4660    Level: intermediate
4661 
4662    Notes:
4663     The result of this call are the same as if one converted the matrix to dense format
4664       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4665 
4666     This code is only implemented for a couple of matrix formats.
4667 
4668 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4669           MatGetRowMax()
4670 @*/
4671 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4672 {
4673   PetscErrorCode ierr;
4674 
4675   PetscFunctionBegin;
4676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4677   PetscValidType(mat,1);
4678   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4679   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4680   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4681   MatCheckPreallocated(mat,1);
4682 
4683   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4684   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4685   PetscFunctionReturn(0);
4686 }
4687 
4688 /*@C
4689    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4690         row of the matrix
4691 
4692    Logically Collective on Mat
4693 
4694    Input Parameters:
4695 .  mat - the matrix
4696 
4697    Output Parameter:
4698 +  v - the vector for storing the minimums
4699 -  idx - the indices of the column found for each row (or NULL if not needed)
4700 
4701    Level: intermediate
4702 
4703    Notes:
4704     if a row is completely empty or has only 0.0 values then the idx[] value for that
4705     row is 0 (the first column).
4706 
4707     This code is only implemented for a couple of matrix formats.
4708 
4709 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4710 @*/
4711 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4712 {
4713   PetscErrorCode ierr;
4714 
4715   PetscFunctionBegin;
4716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4717   PetscValidType(mat,1);
4718   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4719   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4720   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4721   MatCheckPreallocated(mat,1);
4722   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4723 
4724   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4725   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4726   PetscFunctionReturn(0);
4727 }
4728 
4729 /*@C
4730    MatGetRowMax - Gets the maximum value (of the real part) of each
4731         row of the matrix
4732 
4733    Logically Collective on Mat
4734 
4735    Input Parameters:
4736 .  mat - the matrix
4737 
4738    Output Parameter:
4739 +  v - the vector for storing the maximums
4740 -  idx - the indices of the column found for each row (optional)
4741 
4742    Level: intermediate
4743 
4744    Notes:
4745     The result of this call are the same as if one converted the matrix to dense format
4746       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4747 
4748     This code is only implemented for a couple of matrix formats.
4749 
4750 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4751 @*/
4752 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4753 {
4754   PetscErrorCode ierr;
4755 
4756   PetscFunctionBegin;
4757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4758   PetscValidType(mat,1);
4759   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4760   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4761   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4762   MatCheckPreallocated(mat,1);
4763 
4764   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4765   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4766   PetscFunctionReturn(0);
4767 }
4768 
4769 /*@C
4770    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4771         row of the matrix
4772 
4773    Logically Collective on Mat
4774 
4775    Input Parameters:
4776 .  mat - the matrix
4777 
4778    Output Parameter:
4779 +  v - the vector for storing the maximums
4780 -  idx - the indices of the column found for each row (or NULL if not needed)
4781 
4782    Level: intermediate
4783 
4784    Notes:
4785     if a row is completely empty or has only 0.0 values then the idx[] value for that
4786     row is 0 (the first column).
4787 
4788     This code is only implemented for a couple of matrix formats.
4789 
4790 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4791 @*/
4792 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4793 {
4794   PetscErrorCode ierr;
4795 
4796   PetscFunctionBegin;
4797   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4798   PetscValidType(mat,1);
4799   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4800   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4801   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4802   MatCheckPreallocated(mat,1);
4803   if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4804 
4805   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4806   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4807   PetscFunctionReturn(0);
4808 }
4809 
4810 /*@
4811    MatGetRowSum - Gets the sum of each row of the matrix
4812 
4813    Logically or Neighborhood Collective on Mat
4814 
4815    Input Parameters:
4816 .  mat - the matrix
4817 
4818    Output Parameter:
4819 .  v - the vector for storing the sum of rows
4820 
4821    Level: intermediate
4822 
4823    Notes:
4824     This code is slow since it is not currently specialized for different formats
4825 
4826 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4827 @*/
4828 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4829 {
4830   Vec            ones;
4831   PetscErrorCode ierr;
4832 
4833   PetscFunctionBegin;
4834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4835   PetscValidType(mat,1);
4836   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4837   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4838   MatCheckPreallocated(mat,1);
4839   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4840   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4841   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4842   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4843   PetscFunctionReturn(0);
4844 }
4845 
4846 /*@
4847    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4848 
4849    Collective on Mat
4850 
4851    Input Parameter:
4852 +  mat - the matrix to transpose
4853 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4854 
4855    Output Parameters:
4856 .  B - the transpose
4857 
4858    Notes:
4859      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4860 
4861      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4862 
4863      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4864 
4865    Level: intermediate
4866 
4867 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4868 @*/
4869 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4870 {
4871   PetscErrorCode ierr;
4872 
4873   PetscFunctionBegin;
4874   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4875   PetscValidType(mat,1);
4876   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4877   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4878   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4879   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4880   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4881   MatCheckPreallocated(mat,1);
4882 
4883   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4884   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4885   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4886   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4887   PetscFunctionReturn(0);
4888 }
4889 
4890 /*@
4891    MatIsTranspose - Test whether a matrix is another one's transpose,
4892         or its own, in which case it tests symmetry.
4893 
4894    Collective on Mat
4895 
4896    Input Parameter:
4897 +  A - the matrix to test
4898 -  B - the matrix to test against, this can equal the first parameter
4899 
4900    Output Parameters:
4901 .  flg - the result
4902 
4903    Notes:
4904    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4905    has a running time of the order of the number of nonzeros; the parallel
4906    test involves parallel copies of the block-offdiagonal parts of the matrix.
4907 
4908    Level: intermediate
4909 
4910 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4911 @*/
4912 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4913 {
4914   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4915 
4916   PetscFunctionBegin;
4917   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4918   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4919   PetscValidBoolPointer(flg,3);
4920   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4921   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4922   *flg = PETSC_FALSE;
4923   if (f && g) {
4924     if (f == g) {
4925       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4926     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4927   } else {
4928     MatType mattype;
4929     if (!f) {
4930       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4931     } else {
4932       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4933     }
4934     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
4935   }
4936   PetscFunctionReturn(0);
4937 }
4938 
4939 /*@
4940    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4941 
4942    Collective on Mat
4943 
4944    Input Parameter:
4945 +  mat - the matrix to transpose and complex conjugate
4946 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4947 
4948    Output Parameters:
4949 .  B - the Hermitian
4950 
4951    Level: intermediate
4952 
4953 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4954 @*/
4955 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4956 {
4957   PetscErrorCode ierr;
4958 
4959   PetscFunctionBegin;
4960   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4961 #if defined(PETSC_USE_COMPLEX)
4962   ierr = MatConjugate(*B);CHKERRQ(ierr);
4963 #endif
4964   PetscFunctionReturn(0);
4965 }
4966 
4967 /*@
4968    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4969 
4970    Collective on Mat
4971 
4972    Input Parameter:
4973 +  A - the matrix to test
4974 -  B - the matrix to test against, this can equal the first parameter
4975 
4976    Output Parameters:
4977 .  flg - the result
4978 
4979    Notes:
4980    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4981    has a running time of the order of the number of nonzeros; the parallel
4982    test involves parallel copies of the block-offdiagonal parts of the matrix.
4983 
4984    Level: intermediate
4985 
4986 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4987 @*/
4988 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4989 {
4990   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4991 
4992   PetscFunctionBegin;
4993   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4994   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4995   PetscValidBoolPointer(flg,3);
4996   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4997   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4998   if (f && g) {
4999     if (f==g) {
5000       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5001     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5002   }
5003   PetscFunctionReturn(0);
5004 }
5005 
5006 /*@
5007    MatPermute - Creates a new matrix with rows and columns permuted from the
5008    original.
5009 
5010    Collective on Mat
5011 
5012    Input Parameters:
5013 +  mat - the matrix to permute
5014 .  row - row permutation, each processor supplies only the permutation for its rows
5015 -  col - column permutation, each processor supplies only the permutation for its columns
5016 
5017    Output Parameters:
5018 .  B - the permuted matrix
5019 
5020    Level: advanced
5021 
5022    Note:
5023    The index sets map from row/col of permuted matrix to row/col of original matrix.
5024    The index sets should be on the same communicator as Mat and have the same local sizes.
5025 
5026 .seealso: MatGetOrdering(), ISAllGather()
5027 
5028 @*/
5029 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5030 {
5031   PetscErrorCode ierr;
5032 
5033   PetscFunctionBegin;
5034   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5035   PetscValidType(mat,1);
5036   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5037   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5038   PetscValidPointer(B,4);
5039   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5040   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5041   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5042   MatCheckPreallocated(mat,1);
5043 
5044   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5045   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5046   PetscFunctionReturn(0);
5047 }
5048 
5049 /*@
5050    MatEqual - Compares two matrices.
5051 
5052    Collective on Mat
5053 
5054    Input Parameters:
5055 +  A - the first matrix
5056 -  B - the second matrix
5057 
5058    Output Parameter:
5059 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5060 
5061    Level: intermediate
5062 
5063 @*/
5064 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5065 {
5066   PetscErrorCode ierr;
5067 
5068   PetscFunctionBegin;
5069   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5070   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5071   PetscValidType(A,1);
5072   PetscValidType(B,2);
5073   PetscValidBoolPointer(flg,3);
5074   PetscCheckSameComm(A,1,B,2);
5075   MatCheckPreallocated(B,2);
5076   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5077   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5078   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);
5079   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5080   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5081   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);
5082   MatCheckPreallocated(A,1);
5083 
5084   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5085   PetscFunctionReturn(0);
5086 }
5087 
5088 /*@
5089    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5090    matrices that are stored as vectors.  Either of the two scaling
5091    matrices can be NULL.
5092 
5093    Collective on Mat
5094 
5095    Input Parameters:
5096 +  mat - the matrix to be scaled
5097 .  l - the left scaling vector (or NULL)
5098 -  r - the right scaling vector (or NULL)
5099 
5100    Notes:
5101    MatDiagonalScale() computes A = LAR, where
5102    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5103    The L scales the rows of the matrix, the R scales the columns of the matrix.
5104 
5105    Level: intermediate
5106 
5107 
5108 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5109 @*/
5110 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5111 {
5112   PetscErrorCode ierr;
5113 
5114   PetscFunctionBegin;
5115   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5116   PetscValidType(mat,1);
5117   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5118   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5119   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5120   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5121   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5122   MatCheckPreallocated(mat,1);
5123 
5124   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5125   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5126   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5127   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5128   PetscFunctionReturn(0);
5129 }
5130 
5131 /*@
5132     MatScale - Scales all elements of a matrix by a given number.
5133 
5134     Logically Collective on Mat
5135 
5136     Input Parameters:
5137 +   mat - the matrix to be scaled
5138 -   a  - the scaling value
5139 
5140     Output Parameter:
5141 .   mat - the scaled matrix
5142 
5143     Level: intermediate
5144 
5145 .seealso: MatDiagonalScale()
5146 @*/
5147 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5148 {
5149   PetscErrorCode ierr;
5150 
5151   PetscFunctionBegin;
5152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5153   PetscValidType(mat,1);
5154   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5155   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5156   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5157   PetscValidLogicalCollectiveScalar(mat,a,2);
5158   MatCheckPreallocated(mat,1);
5159 
5160   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5161   if (a != (PetscScalar)1.0) {
5162     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5163     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5164   }
5165   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5166   PetscFunctionReturn(0);
5167 }
5168 
5169 /*@
5170    MatNorm - Calculates various norms of a matrix.
5171 
5172    Collective on Mat
5173 
5174    Input Parameters:
5175 +  mat - the matrix
5176 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5177 
5178    Output Parameters:
5179 .  nrm - the resulting norm
5180 
5181    Level: intermediate
5182 
5183 @*/
5184 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5185 {
5186   PetscErrorCode ierr;
5187 
5188   PetscFunctionBegin;
5189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5190   PetscValidType(mat,1);
5191   PetscValidScalarPointer(nrm,3);
5192 
5193   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5194   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5195   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5196   MatCheckPreallocated(mat,1);
5197 
5198   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5199   PetscFunctionReturn(0);
5200 }
5201 
5202 /*
5203      This variable is used to prevent counting of MatAssemblyBegin() that
5204    are called from within a MatAssemblyEnd().
5205 */
5206 static PetscInt MatAssemblyEnd_InUse = 0;
5207 /*@
5208    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5209    be called after completing all calls to MatSetValues().
5210 
5211    Collective on Mat
5212 
5213    Input Parameters:
5214 +  mat - the matrix
5215 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5216 
5217    Notes:
5218    MatSetValues() generally caches the values.  The matrix is ready to
5219    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5220    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5221    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5222    using the matrix.
5223 
5224    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5225    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
5226    a global collective operation requring all processes that share the matrix.
5227 
5228    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5229    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5230    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5231 
5232    Level: beginner
5233 
5234 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5235 @*/
5236 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5237 {
5238   PetscErrorCode ierr;
5239 
5240   PetscFunctionBegin;
5241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5242   PetscValidType(mat,1);
5243   MatCheckPreallocated(mat,1);
5244   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5245   if (mat->assembled) {
5246     mat->was_assembled = PETSC_TRUE;
5247     mat->assembled     = PETSC_FALSE;
5248   }
5249 
5250   if (!MatAssemblyEnd_InUse) {
5251     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5252     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5253     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5254   } else if (mat->ops->assemblybegin) {
5255     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5256   }
5257   PetscFunctionReturn(0);
5258 }
5259 
5260 /*@
5261    MatAssembled - Indicates if a matrix has been assembled and is ready for
5262      use; for example, in matrix-vector product.
5263 
5264    Not Collective
5265 
5266    Input Parameter:
5267 .  mat - the matrix
5268 
5269    Output Parameter:
5270 .  assembled - PETSC_TRUE or PETSC_FALSE
5271 
5272    Level: advanced
5273 
5274 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5275 @*/
5276 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5277 {
5278   PetscFunctionBegin;
5279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5280   PetscValidPointer(assembled,2);
5281   *assembled = mat->assembled;
5282   PetscFunctionReturn(0);
5283 }
5284 
5285 /*@
5286    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5287    be called after MatAssemblyBegin().
5288 
5289    Collective on Mat
5290 
5291    Input Parameters:
5292 +  mat - the matrix
5293 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5294 
5295    Options Database Keys:
5296 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5297 .  -mat_view ::ascii_info_detail - Prints more detailed info
5298 .  -mat_view - Prints matrix in ASCII format
5299 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5300 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5301 .  -display <name> - Sets display name (default is host)
5302 .  -draw_pause <sec> - Sets number of seconds to pause after display
5303 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5304 .  -viewer_socket_machine <machine> - Machine to use for socket
5305 .  -viewer_socket_port <port> - Port number to use for socket
5306 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5307 
5308    Notes:
5309    MatSetValues() generally caches the values.  The matrix is ready to
5310    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5311    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5312    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5313    using the matrix.
5314 
5315    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5316    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5317    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5318 
5319    Level: beginner
5320 
5321 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5322 @*/
5323 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5324 {
5325   PetscErrorCode  ierr;
5326   static PetscInt inassm = 0;
5327   PetscBool       flg    = PETSC_FALSE;
5328 
5329   PetscFunctionBegin;
5330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5331   PetscValidType(mat,1);
5332 
5333   inassm++;
5334   MatAssemblyEnd_InUse++;
5335   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5336     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5337     if (mat->ops->assemblyend) {
5338       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5339     }
5340     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5341   } else if (mat->ops->assemblyend) {
5342     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5343   }
5344 
5345   /* Flush assembly is not a true assembly */
5346   if (type != MAT_FLUSH_ASSEMBLY) {
5347     mat->num_ass++;
5348     mat->assembled        = PETSC_TRUE;
5349     mat->ass_nonzerostate = mat->nonzerostate;
5350   }
5351 
5352   mat->insertmode = NOT_SET_VALUES;
5353   MatAssemblyEnd_InUse--;
5354   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5355   if (!mat->symmetric_eternal) {
5356     mat->symmetric_set              = PETSC_FALSE;
5357     mat->hermitian_set              = PETSC_FALSE;
5358     mat->structurally_symmetric_set = PETSC_FALSE;
5359   }
5360   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5361     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5362 
5363     if (mat->checksymmetryonassembly) {
5364       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5365       if (flg) {
5366         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5367       } else {
5368         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5369       }
5370     }
5371     if (mat->nullsp && mat->checknullspaceonassembly) {
5372       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5373     }
5374   }
5375   inassm--;
5376   PetscFunctionReturn(0);
5377 }
5378 
5379 /*@
5380    MatSetOption - Sets a parameter option for a matrix. Some options
5381    may be specific to certain storage formats.  Some options
5382    determine how values will be inserted (or added). Sorted,
5383    row-oriented input will generally assemble the fastest. The default
5384    is row-oriented.
5385 
5386    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5387 
5388    Input Parameters:
5389 +  mat - the matrix
5390 .  option - the option, one of those listed below (and possibly others),
5391 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5392 
5393   Options Describing Matrix Structure:
5394 +    MAT_SPD - symmetric positive definite
5395 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5396 .    MAT_HERMITIAN - transpose is the complex conjugation
5397 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5398 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5399                             you set to be kept with all future use of the matrix
5400                             including after MatAssemblyBegin/End() which could
5401                             potentially change the symmetry structure, i.e. you
5402                             KNOW the matrix will ALWAYS have the property you set.
5403                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5404                             the relevant flags must be set independently.
5405 
5406 
5407    Options For Use with MatSetValues():
5408    Insert a logically dense subblock, which can be
5409 .    MAT_ROW_ORIENTED - row-oriented (default)
5410 
5411    Note these options reflect the data you pass in with MatSetValues(); it has
5412    nothing to do with how the data is stored internally in the matrix
5413    data structure.
5414 
5415    When (re)assembling a matrix, we can restrict the input for
5416    efficiency/debugging purposes.  These options include:
5417 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5418 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5419 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5420 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5421 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5422 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5423         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5424         performance for very large process counts.
5425 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5426         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5427         functions, instead sending only neighbor messages.
5428 
5429    Notes:
5430    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5431 
5432    Some options are relevant only for particular matrix types and
5433    are thus ignored by others.  Other options are not supported by
5434    certain matrix types and will generate an error message if set.
5435 
5436    If using a Fortran 77 module to compute a matrix, one may need to
5437    use the column-oriented option (or convert to the row-oriented
5438    format).
5439 
5440    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5441    that would generate a new entry in the nonzero structure is instead
5442    ignored.  Thus, if memory has not alredy been allocated for this particular
5443    data, then the insertion is ignored. For dense matrices, in which
5444    the entire array is allocated, no entries are ever ignored.
5445    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5446 
5447    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5448    that would generate a new entry in the nonzero structure instead produces
5449    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
5450 
5451    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5452    that would generate a new entry that has not been preallocated will
5453    instead produce an error. (Currently supported for AIJ and BAIJ formats
5454    only.) This is a useful flag when debugging matrix memory preallocation.
5455    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5456 
5457    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5458    other processors should be dropped, rather than stashed.
5459    This is useful if you know that the "owning" processor is also
5460    always generating the correct matrix entries, so that PETSc need
5461    not transfer duplicate entries generated on another processor.
5462 
5463    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5464    searches during matrix assembly. When this flag is set, the hash table
5465    is created during the first Matrix Assembly. This hash table is
5466    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5467    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5468    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5469    supported by MATMPIBAIJ format only.
5470 
5471    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5472    are kept in the nonzero structure
5473 
5474    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5475    a zero location in the matrix
5476 
5477    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5478 
5479    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5480         zero row routines and thus improves performance for very large process counts.
5481 
5482    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5483         part of the matrix (since they should match the upper triangular part).
5484 
5485    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5486                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5487                      with finite difference schemes with non-periodic boundary conditions.
5488    Notes:
5489     Can only be called after MatSetSizes() and MatSetType() have been set.
5490 
5491    Level: intermediate
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->assembly_subset = flg;
5518     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5519 #if !defined(PETSC_HAVE_MPIUNI)
5520       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5521 #endif
5522       mat->stash.first_assembly_done = PETSC_FALSE;
5523     }
5524     PetscFunctionReturn(0);
5525   case MAT_NO_OFF_PROC_ZERO_ROWS:
5526     mat->nooffproczerorows = flg;
5527     PetscFunctionReturn(0);
5528     break;
5529   case MAT_SPD:
5530     mat->spd_set = PETSC_TRUE;
5531     mat->spd     = flg;
5532     if (flg) {
5533       mat->symmetric                  = PETSC_TRUE;
5534       mat->structurally_symmetric     = PETSC_TRUE;
5535       mat->symmetric_set              = PETSC_TRUE;
5536       mat->structurally_symmetric_set = PETSC_TRUE;
5537     }
5538     break;
5539   case MAT_SYMMETRIC:
5540     mat->symmetric = flg;
5541     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5542     mat->symmetric_set              = PETSC_TRUE;
5543     mat->structurally_symmetric_set = flg;
5544 #if !defined(PETSC_USE_COMPLEX)
5545     mat->hermitian     = flg;
5546     mat->hermitian_set = PETSC_TRUE;
5547 #endif
5548     break;
5549   case MAT_HERMITIAN:
5550     mat->hermitian = flg;
5551     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5552     mat->hermitian_set              = PETSC_TRUE;
5553     mat->structurally_symmetric_set = flg;
5554 #if !defined(PETSC_USE_COMPLEX)
5555     mat->symmetric     = flg;
5556     mat->symmetric_set = PETSC_TRUE;
5557 #endif
5558     break;
5559   case MAT_STRUCTURALLY_SYMMETRIC:
5560     mat->structurally_symmetric     = flg;
5561     mat->structurally_symmetric_set = PETSC_TRUE;
5562     break;
5563   case MAT_SYMMETRY_ETERNAL:
5564     mat->symmetric_eternal = flg;
5565     break;
5566   case MAT_STRUCTURE_ONLY:
5567     mat->structure_only = flg;
5568     break;
5569   case MAT_SORTED_FULL:
5570     mat->sortedfull = flg;
5571     break;
5572   default:
5573     break;
5574   }
5575   if (mat->ops->setoption) {
5576     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5577   }
5578   PetscFunctionReturn(0);
5579 }
5580 
5581 /*@
5582    MatGetOption - Gets a parameter option that has been set for a matrix.
5583 
5584    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5585 
5586    Input Parameters:
5587 +  mat - the matrix
5588 -  option - the option, this only responds to certain options, check the code for which ones
5589 
5590    Output Parameter:
5591 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5592 
5593     Notes:
5594     Can only be called after MatSetSizes() and MatSetType() have been set.
5595 
5596    Level: intermediate
5597 
5598 .seealso:  MatOption, MatSetOption()
5599 
5600 @*/
5601 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5602 {
5603   PetscFunctionBegin;
5604   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5605   PetscValidType(mat,1);
5606 
5607   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);
5608   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()");
5609 
5610   switch (op) {
5611   case MAT_NO_OFF_PROC_ENTRIES:
5612     *flg = mat->nooffprocentries;
5613     break;
5614   case MAT_NO_OFF_PROC_ZERO_ROWS:
5615     *flg = mat->nooffproczerorows;
5616     break;
5617   case MAT_SYMMETRIC:
5618     *flg = mat->symmetric;
5619     break;
5620   case MAT_HERMITIAN:
5621     *flg = mat->hermitian;
5622     break;
5623   case MAT_STRUCTURALLY_SYMMETRIC:
5624     *flg = mat->structurally_symmetric;
5625     break;
5626   case MAT_SYMMETRY_ETERNAL:
5627     *flg = mat->symmetric_eternal;
5628     break;
5629   case MAT_SPD:
5630     *flg = mat->spd;
5631     break;
5632   default:
5633     break;
5634   }
5635   PetscFunctionReturn(0);
5636 }
5637 
5638 /*@
5639    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5640    this routine retains the old nonzero structure.
5641 
5642    Logically Collective on Mat
5643 
5644    Input Parameters:
5645 .  mat - the matrix
5646 
5647    Level: intermediate
5648 
5649    Notes:
5650     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.
5651    See the Performance chapter of the users manual for information on preallocating matrices.
5652 
5653 .seealso: MatZeroRows()
5654 @*/
5655 PetscErrorCode MatZeroEntries(Mat mat)
5656 {
5657   PetscErrorCode ierr;
5658 
5659   PetscFunctionBegin;
5660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5661   PetscValidType(mat,1);
5662   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5663   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");
5664   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5665   MatCheckPreallocated(mat,1);
5666 
5667   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5668   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5669   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5670   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
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 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5708           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5709 @*/
5710 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5711 {
5712   PetscErrorCode ierr;
5713 
5714   PetscFunctionBegin;
5715   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5716   PetscValidType(mat,1);
5717   if (numRows) PetscValidIntPointer(rows,3);
5718   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5719   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5720   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5721   MatCheckPreallocated(mat,1);
5722 
5723   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5724   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5725   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5726   PetscFunctionReturn(0);
5727 }
5728 
5729 /*@
5730    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5731    of a set of rows and columns of a matrix.
5732 
5733    Collective on Mat
5734 
5735    Input Parameters:
5736 +  mat - the matrix
5737 .  is - the rows to zero
5738 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5739 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5740 -  b - optional vector of right hand side, that will be adjusted by provided solution
5741 
5742    Notes:
5743    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5744 
5745    The user can set a value in the diagonal entry (or for the AIJ and
5746    row formats can optionally remove the main diagonal entry from the
5747    nonzero structure as well, by passing 0.0 as the final argument).
5748 
5749    For the parallel case, all processes that share the matrix (i.e.,
5750    those in the communicator used for matrix creation) MUST call this
5751    routine, regardless of whether any rows being zeroed are owned by
5752    them.
5753 
5754    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5755    list only rows local to itself).
5756 
5757    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5758 
5759    Level: intermediate
5760 
5761 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5762           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5763 @*/
5764 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5765 {
5766   PetscErrorCode ierr;
5767   PetscInt       numRows;
5768   const PetscInt *rows;
5769 
5770   PetscFunctionBegin;
5771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5772   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5773   PetscValidType(mat,1);
5774   PetscValidType(is,2);
5775   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5776   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5777   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5778   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5779   PetscFunctionReturn(0);
5780 }
5781 
5782 /*@
5783    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5784    of a set of rows of a matrix.
5785 
5786    Collective on Mat
5787 
5788    Input Parameters:
5789 +  mat - the matrix
5790 .  numRows - the number of rows to remove
5791 .  rows - the global row indices
5792 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5793 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5794 -  b - optional vector of right hand side, that will be adjusted by provided solution
5795 
5796    Notes:
5797    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5798    but does not release memory.  For the dense and block diagonal
5799    formats this does not alter the nonzero structure.
5800 
5801    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5802    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5803    merely zeroed.
5804 
5805    The user can set a value in the diagonal entry (or for the AIJ and
5806    row formats can optionally remove the main diagonal entry from the
5807    nonzero structure as well, by passing 0.0 as the final argument).
5808 
5809    For the parallel case, all processes that share the matrix (i.e.,
5810    those in the communicator used for matrix creation) MUST call this
5811    routine, regardless of whether any rows being zeroed are owned by
5812    them.
5813 
5814    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5815    list only rows local to itself).
5816 
5817    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5818    owns that are to be zeroed. This saves a global synchronization in the implementation.
5819 
5820    Level: intermediate
5821 
5822 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5823           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5824 @*/
5825 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5826 {
5827   PetscErrorCode ierr;
5828 
5829   PetscFunctionBegin;
5830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5831   PetscValidType(mat,1);
5832   if (numRows) PetscValidIntPointer(rows,3);
5833   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5834   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5835   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5836   MatCheckPreallocated(mat,1);
5837 
5838   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5839   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5840   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5841   PetscFunctionReturn(0);
5842 }
5843 
5844 /*@
5845    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5846    of a set of rows of a matrix.
5847 
5848    Collective on Mat
5849 
5850    Input Parameters:
5851 +  mat - the matrix
5852 .  is - index set of rows to remove
5853 .  diag - value put in all diagonals of eliminated rows
5854 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5855 -  b - optional vector of right hand side, that will be adjusted by provided solution
5856 
5857    Notes:
5858    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5859    but does not release memory.  For the dense and block diagonal
5860    formats this does not alter the nonzero structure.
5861 
5862    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5863    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5864    merely zeroed.
5865 
5866    The user can set a value in the diagonal entry (or for the AIJ and
5867    row formats can optionally remove the main diagonal entry from the
5868    nonzero structure as well, by passing 0.0 as the final argument).
5869 
5870    For the parallel case, all processes that share the matrix (i.e.,
5871    those in the communicator used for matrix creation) MUST call this
5872    routine, regardless of whether any rows being zeroed are owned by
5873    them.
5874 
5875    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5876    list only rows local to itself).
5877 
5878    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5879    owns that are to be zeroed. This saves a global synchronization in the implementation.
5880 
5881    Level: intermediate
5882 
5883 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5884           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5885 @*/
5886 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5887 {
5888   PetscInt       numRows;
5889   const PetscInt *rows;
5890   PetscErrorCode ierr;
5891 
5892   PetscFunctionBegin;
5893   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5894   PetscValidType(mat,1);
5895   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5896   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5897   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5898   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5899   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5900   PetscFunctionReturn(0);
5901 }
5902 
5903 /*@
5904    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5905    of a set of rows of a matrix. These rows must be local to the process.
5906 
5907    Collective on Mat
5908 
5909    Input Parameters:
5910 +  mat - the matrix
5911 .  numRows - the number of rows to remove
5912 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5913 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5914 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5915 -  b - optional vector of right hand side, that will be adjusted by provided solution
5916 
5917    Notes:
5918    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5919    but does not release memory.  For the dense and block diagonal
5920    formats this does not alter the nonzero structure.
5921 
5922    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5923    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5924    merely zeroed.
5925 
5926    The user can set a value in the diagonal entry (or for the AIJ and
5927    row formats can optionally remove the main diagonal entry from the
5928    nonzero structure as well, by passing 0.0 as the final argument).
5929 
5930    For the parallel case, all processes that share the matrix (i.e.,
5931    those in the communicator used for matrix creation) MUST call this
5932    routine, regardless of whether any rows being zeroed are owned by
5933    them.
5934 
5935    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5936    list only rows local to itself).
5937 
5938    The grid coordinates are across the entire grid, not just the local portion
5939 
5940    In Fortran idxm and idxn should be declared as
5941 $     MatStencil idxm(4,m)
5942    and the values inserted using
5943 $    idxm(MatStencil_i,1) = i
5944 $    idxm(MatStencil_j,1) = j
5945 $    idxm(MatStencil_k,1) = k
5946 $    idxm(MatStencil_c,1) = c
5947    etc
5948 
5949    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5950    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5951    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5952    DM_BOUNDARY_PERIODIC boundary type.
5953 
5954    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
5955    a single value per point) you can skip filling those indices.
5956 
5957    Level: intermediate
5958 
5959 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5960           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5961 @*/
5962 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5963 {
5964   PetscInt       dim     = mat->stencil.dim;
5965   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5966   PetscInt       *dims   = mat->stencil.dims+1;
5967   PetscInt       *starts = mat->stencil.starts;
5968   PetscInt       *dxm    = (PetscInt*) rows;
5969   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5970   PetscErrorCode ierr;
5971 
5972   PetscFunctionBegin;
5973   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5974   PetscValidType(mat,1);
5975   if (numRows) PetscValidIntPointer(rows,3);
5976 
5977   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5978   for (i = 0; i < numRows; ++i) {
5979     /* Skip unused dimensions (they are ordered k, j, i, c) */
5980     for (j = 0; j < 3-sdim; ++j) dxm++;
5981     /* Local index in X dir */
5982     tmp = *dxm++ - starts[0];
5983     /* Loop over remaining dimensions */
5984     for (j = 0; j < dim-1; ++j) {
5985       /* If nonlocal, set index to be negative */
5986       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5987       /* Update local index */
5988       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5989     }
5990     /* Skip component slot if necessary */
5991     if (mat->stencil.noc) dxm++;
5992     /* Local row number */
5993     if (tmp >= 0) {
5994       jdxm[numNewRows++] = tmp;
5995     }
5996   }
5997   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5998   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5999   PetscFunctionReturn(0);
6000 }
6001 
6002 /*@
6003    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6004    of a set of rows and columns of a matrix.
6005 
6006    Collective on Mat
6007 
6008    Input Parameters:
6009 +  mat - the matrix
6010 .  numRows - the number of rows/columns to remove
6011 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6012 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6013 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6014 -  b - optional vector of right hand side, that will be adjusted by provided solution
6015 
6016    Notes:
6017    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6018    but does not release memory.  For the dense and block diagonal
6019    formats this does not alter the nonzero structure.
6020 
6021    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6022    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6023    merely zeroed.
6024 
6025    The user can set a value in the diagonal entry (or for the AIJ and
6026    row formats can optionally remove the main diagonal entry from the
6027    nonzero structure as well, by passing 0.0 as the final argument).
6028 
6029    For the parallel case, all processes that share the matrix (i.e.,
6030    those in the communicator used for matrix creation) MUST call this
6031    routine, regardless of whether any rows being zeroed are owned by
6032    them.
6033 
6034    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6035    list only rows local to itself, but the row/column numbers are given in local numbering).
6036 
6037    The grid coordinates are across the entire grid, not just the local portion
6038 
6039    In Fortran idxm and idxn should be declared as
6040 $     MatStencil idxm(4,m)
6041    and the values inserted using
6042 $    idxm(MatStencil_i,1) = i
6043 $    idxm(MatStencil_j,1) = j
6044 $    idxm(MatStencil_k,1) = k
6045 $    idxm(MatStencil_c,1) = c
6046    etc
6047 
6048    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6049    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6050    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6051    DM_BOUNDARY_PERIODIC boundary type.
6052 
6053    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
6054    a single value per point) you can skip filling those indices.
6055 
6056    Level: intermediate
6057 
6058 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6059           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6060 @*/
6061 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6062 {
6063   PetscInt       dim     = mat->stencil.dim;
6064   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6065   PetscInt       *dims   = mat->stencil.dims+1;
6066   PetscInt       *starts = mat->stencil.starts;
6067   PetscInt       *dxm    = (PetscInt*) rows;
6068   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6069   PetscErrorCode ierr;
6070 
6071   PetscFunctionBegin;
6072   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6073   PetscValidType(mat,1);
6074   if (numRows) PetscValidIntPointer(rows,3);
6075 
6076   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6077   for (i = 0; i < numRows; ++i) {
6078     /* Skip unused dimensions (they are ordered k, j, i, c) */
6079     for (j = 0; j < 3-sdim; ++j) dxm++;
6080     /* Local index in X dir */
6081     tmp = *dxm++ - starts[0];
6082     /* Loop over remaining dimensions */
6083     for (j = 0; j < dim-1; ++j) {
6084       /* If nonlocal, set index to be negative */
6085       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6086       /* Update local index */
6087       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6088     }
6089     /* Skip component slot if necessary */
6090     if (mat->stencil.noc) dxm++;
6091     /* Local row number */
6092     if (tmp >= 0) {
6093       jdxm[numNewRows++] = tmp;
6094     }
6095   }
6096   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6097   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6098   PetscFunctionReturn(0);
6099 }
6100 
6101 /*@C
6102    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6103    of a set of rows of a matrix; using local numbering of rows.
6104 
6105    Collective on Mat
6106 
6107    Input Parameters:
6108 +  mat - the matrix
6109 .  numRows - the number of rows to remove
6110 .  rows - the global row indices
6111 .  diag - value put in all diagonals of eliminated rows
6112 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6113 -  b - optional vector of right hand side, that will be adjusted by provided solution
6114 
6115    Notes:
6116    Before calling MatZeroRowsLocal(), the user must first set the
6117    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6118 
6119    For the AIJ matrix formats this removes the old nonzero structure,
6120    but does not release memory.  For the dense and block diagonal
6121    formats this does not alter the nonzero structure.
6122 
6123    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6124    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6125    merely zeroed.
6126 
6127    The user can set a value in the diagonal entry (or for the AIJ and
6128    row formats can optionally remove the main diagonal entry from the
6129    nonzero structure as well, by passing 0.0 as the final argument).
6130 
6131    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6132    owns that are to be zeroed. This saves a global synchronization in the implementation.
6133 
6134    Level: intermediate
6135 
6136 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6137           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6138 @*/
6139 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6140 {
6141   PetscErrorCode ierr;
6142 
6143   PetscFunctionBegin;
6144   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6145   PetscValidType(mat,1);
6146   if (numRows) PetscValidIntPointer(rows,3);
6147   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6148   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6149   MatCheckPreallocated(mat,1);
6150 
6151   if (mat->ops->zerorowslocal) {
6152     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6153   } else {
6154     IS             is, newis;
6155     const PetscInt *newRows;
6156 
6157     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6158     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6159     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6160     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6161     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6162     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6163     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6164     ierr = ISDestroy(&is);CHKERRQ(ierr);
6165   }
6166   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6167   PetscFunctionReturn(0);
6168 }
6169 
6170 /*@
6171    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6172    of a set of rows of a matrix; using local numbering of rows.
6173 
6174    Collective on Mat
6175 
6176    Input Parameters:
6177 +  mat - the matrix
6178 .  is - index set of rows to remove
6179 .  diag - value put in all diagonals of eliminated rows
6180 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6181 -  b - optional vector of right hand side, that will be adjusted by provided solution
6182 
6183    Notes:
6184    Before calling MatZeroRowsLocalIS(), the user must first set the
6185    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6186 
6187    For the AIJ matrix formats this removes the old nonzero structure,
6188    but does not release memory.  For the dense and block diagonal
6189    formats this does not alter the nonzero structure.
6190 
6191    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6192    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6193    merely zeroed.
6194 
6195    The user can set a value in the diagonal entry (or for the AIJ and
6196    row formats can optionally remove the main diagonal entry from the
6197    nonzero structure as well, by passing 0.0 as the final argument).
6198 
6199    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6200    owns that are to be zeroed. This saves a global synchronization in the implementation.
6201 
6202    Level: intermediate
6203 
6204 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6205           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6206 @*/
6207 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6208 {
6209   PetscErrorCode ierr;
6210   PetscInt       numRows;
6211   const PetscInt *rows;
6212 
6213   PetscFunctionBegin;
6214   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6215   PetscValidType(mat,1);
6216   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6217   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6218   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6219   MatCheckPreallocated(mat,1);
6220 
6221   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6222   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6223   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6224   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6225   PetscFunctionReturn(0);
6226 }
6227 
6228 /*@
6229    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6230    of a set of rows and columns of a matrix; using local numbering of rows.
6231 
6232    Collective on Mat
6233 
6234    Input Parameters:
6235 +  mat - the matrix
6236 .  numRows - the number of rows to remove
6237 .  rows - the global row indices
6238 .  diag - value put in all diagonals of eliminated rows
6239 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6240 -  b - optional vector of right hand side, that will be adjusted by provided solution
6241 
6242    Notes:
6243    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6244    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6245 
6246    The user can set a value in the diagonal entry (or for the AIJ and
6247    row formats can optionally remove the main diagonal entry from the
6248    nonzero structure as well, by passing 0.0 as the final argument).
6249 
6250    Level: intermediate
6251 
6252 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6253           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6254 @*/
6255 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6256 {
6257   PetscErrorCode ierr;
6258   IS             is, newis;
6259   const PetscInt *newRows;
6260 
6261   PetscFunctionBegin;
6262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6263   PetscValidType(mat,1);
6264   if (numRows) PetscValidIntPointer(rows,3);
6265   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6266   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6267   MatCheckPreallocated(mat,1);
6268 
6269   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6270   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6271   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6272   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6273   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6274   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6275   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6276   ierr = ISDestroy(&is);CHKERRQ(ierr);
6277   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6278   PetscFunctionReturn(0);
6279 }
6280 
6281 /*@
6282    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6283    of a set of rows and columns of a matrix; using local numbering of rows.
6284 
6285    Collective on Mat
6286 
6287    Input Parameters:
6288 +  mat - the matrix
6289 .  is - index set of rows to remove
6290 .  diag - value put in all diagonals of eliminated rows
6291 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6292 -  b - optional vector of right hand side, that will be adjusted by provided solution
6293 
6294    Notes:
6295    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6296    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6297 
6298    The user can set a value in the diagonal entry (or for the AIJ and
6299    row formats can optionally remove the main diagonal entry from the
6300    nonzero structure as well, by passing 0.0 as the final argument).
6301 
6302    Level: intermediate
6303 
6304 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6305           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6306 @*/
6307 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6308 {
6309   PetscErrorCode ierr;
6310   PetscInt       numRows;
6311   const PetscInt *rows;
6312 
6313   PetscFunctionBegin;
6314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6315   PetscValidType(mat,1);
6316   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6317   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6318   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6319   MatCheckPreallocated(mat,1);
6320 
6321   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6322   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6323   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6324   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6325   PetscFunctionReturn(0);
6326 }
6327 
6328 /*@C
6329    MatGetSize - Returns the numbers of rows and columns in a matrix.
6330 
6331    Not Collective
6332 
6333    Input Parameter:
6334 .  mat - the matrix
6335 
6336    Output Parameters:
6337 +  m - the number of global rows
6338 -  n - the number of global columns
6339 
6340    Note: both output parameters can be NULL on input.
6341 
6342    Level: beginner
6343 
6344 .seealso: MatGetLocalSize()
6345 @*/
6346 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6347 {
6348   PetscFunctionBegin;
6349   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6350   if (m) *m = mat->rmap->N;
6351   if (n) *n = mat->cmap->N;
6352   PetscFunctionReturn(0);
6353 }
6354 
6355 /*@C
6356    MatGetLocalSize - Returns the number of rows and columns in a matrix
6357    stored locally.  This information may be implementation dependent, so
6358    use with care.
6359 
6360    Not Collective
6361 
6362    Input Parameters:
6363 .  mat - the matrix
6364 
6365    Output Parameters:
6366 +  m - the number of local rows
6367 -  n - the number of local columns
6368 
6369    Note: both output parameters can be NULL on input.
6370 
6371    Level: beginner
6372 
6373 .seealso: MatGetSize()
6374 @*/
6375 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6376 {
6377   PetscFunctionBegin;
6378   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6379   if (m) PetscValidIntPointer(m,2);
6380   if (n) PetscValidIntPointer(n,3);
6381   if (m) *m = mat->rmap->n;
6382   if (n) *n = mat->cmap->n;
6383   PetscFunctionReturn(0);
6384 }
6385 
6386 /*@C
6387    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6388    this processor. (The columns of the "diagonal block")
6389 
6390    Not Collective, unless matrix has not been allocated, then collective on Mat
6391 
6392    Input Parameters:
6393 .  mat - the matrix
6394 
6395    Output Parameters:
6396 +  m - the global index of the first local column
6397 -  n - one more than the global index of the last local column
6398 
6399    Notes:
6400     both output parameters can be NULL on input.
6401 
6402    Level: developer
6403 
6404 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6405 
6406 @*/
6407 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6408 {
6409   PetscFunctionBegin;
6410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6411   PetscValidType(mat,1);
6412   if (m) PetscValidIntPointer(m,2);
6413   if (n) PetscValidIntPointer(n,3);
6414   MatCheckPreallocated(mat,1);
6415   if (m) *m = mat->cmap->rstart;
6416   if (n) *n = mat->cmap->rend;
6417   PetscFunctionReturn(0);
6418 }
6419 
6420 /*@C
6421    MatGetOwnershipRange - Returns the range of matrix rows owned by
6422    this processor, assuming that the matrix is laid out with the first
6423    n1 rows on the first processor, the next n2 rows on the second, etc.
6424    For certain parallel layouts this range may not be well defined.
6425 
6426    Not Collective
6427 
6428    Input Parameters:
6429 .  mat - the matrix
6430 
6431    Output Parameters:
6432 +  m - the global index of the first local row
6433 -  n - one more than the global index of the last local row
6434 
6435    Note: Both output parameters can be NULL on input.
6436 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6437 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6438 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6439 
6440    Level: beginner
6441 
6442 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6443 
6444 @*/
6445 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6446 {
6447   PetscFunctionBegin;
6448   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6449   PetscValidType(mat,1);
6450   if (m) PetscValidIntPointer(m,2);
6451   if (n) PetscValidIntPointer(n,3);
6452   MatCheckPreallocated(mat,1);
6453   if (m) *m = mat->rmap->rstart;
6454   if (n) *n = mat->rmap->rend;
6455   PetscFunctionReturn(0);
6456 }
6457 
6458 /*@C
6459    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6460    each process
6461 
6462    Not Collective, unless matrix has not been allocated, then collective on Mat
6463 
6464    Input Parameters:
6465 .  mat - the matrix
6466 
6467    Output Parameters:
6468 .  ranges - start of each processors portion plus one more than the total length at the end
6469 
6470    Level: beginner
6471 
6472 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6473 
6474 @*/
6475 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6476 {
6477   PetscErrorCode ierr;
6478 
6479   PetscFunctionBegin;
6480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6481   PetscValidType(mat,1);
6482   MatCheckPreallocated(mat,1);
6483   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6484   PetscFunctionReturn(0);
6485 }
6486 
6487 /*@C
6488    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6489    this processor. (The columns of the "diagonal blocks" for each process)
6490 
6491    Not Collective, unless matrix has not been allocated, then collective on Mat
6492 
6493    Input Parameters:
6494 .  mat - the matrix
6495 
6496    Output Parameters:
6497 .  ranges - start of each processors portion plus one more then the total length at the end
6498 
6499    Level: beginner
6500 
6501 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6502 
6503 @*/
6504 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6505 {
6506   PetscErrorCode ierr;
6507 
6508   PetscFunctionBegin;
6509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6510   PetscValidType(mat,1);
6511   MatCheckPreallocated(mat,1);
6512   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6513   PetscFunctionReturn(0);
6514 }
6515 
6516 /*@C
6517    MatGetOwnershipIS - Get row and column ownership as index sets
6518 
6519    Not Collective
6520 
6521    Input Arguments:
6522 .  A - matrix of type Elemental
6523 
6524    Output Arguments:
6525 +  rows - rows in which this process owns elements
6526 -  cols - columns in which this process owns elements
6527 
6528    Level: intermediate
6529 
6530 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6531 @*/
6532 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6533 {
6534   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6535 
6536   PetscFunctionBegin;
6537   MatCheckPreallocated(A,1);
6538   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6539   if (f) {
6540     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6541   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6542     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6543     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6544   }
6545   PetscFunctionReturn(0);
6546 }
6547 
6548 /*@C
6549    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6550    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6551    to complete the factorization.
6552 
6553    Collective on Mat
6554 
6555    Input Parameters:
6556 +  mat - the matrix
6557 .  row - row permutation
6558 .  column - column permutation
6559 -  info - structure containing
6560 $      levels - number of levels of fill.
6561 $      expected fill - as ratio of original fill.
6562 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6563                 missing diagonal entries)
6564 
6565    Output Parameters:
6566 .  fact - new matrix that has been symbolically factored
6567 
6568    Notes:
6569     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6570 
6571    Most users should employ the simplified KSP interface for linear solvers
6572    instead of working directly with matrix algebra routines such as this.
6573    See, e.g., KSPCreate().
6574 
6575    Level: developer
6576 
6577 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6578           MatGetOrdering(), MatFactorInfo
6579 
6580     Note: this uses the definition of level of fill as in Y. Saad, 2003
6581 
6582     Developer Note: fortran interface is not autogenerated as the f90
6583     interface defintion cannot be generated correctly [due to MatFactorInfo]
6584 
6585    References:
6586      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6587 @*/
6588 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6589 {
6590   PetscErrorCode ierr;
6591 
6592   PetscFunctionBegin;
6593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6594   PetscValidType(mat,1);
6595   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6596   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6597   PetscValidPointer(info,4);
6598   PetscValidPointer(fact,5);
6599   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6600   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6601   if (!(fact)->ops->ilufactorsymbolic) {
6602     MatSolverType spackage;
6603     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6604     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6605   }
6606   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6607   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6608   MatCheckPreallocated(mat,2);
6609 
6610   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6611   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6612   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6613   PetscFunctionReturn(0);
6614 }
6615 
6616 /*@C
6617    MatICCFactorSymbolic - Performs symbolic incomplete
6618    Cholesky factorization for a symmetric matrix.  Use
6619    MatCholeskyFactorNumeric() to complete the factorization.
6620 
6621    Collective on Mat
6622 
6623    Input Parameters:
6624 +  mat - the matrix
6625 .  perm - row and column permutation
6626 -  info - structure containing
6627 $      levels - number of levels of fill.
6628 $      expected fill - as ratio of original fill.
6629 
6630    Output Parameter:
6631 .  fact - the factored matrix
6632 
6633    Notes:
6634    Most users should employ the KSP interface for linear solvers
6635    instead of working directly with matrix algebra routines such as this.
6636    See, e.g., KSPCreate().
6637 
6638    Level: developer
6639 
6640 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6641 
6642     Note: this uses the definition of level of fill as in Y. Saad, 2003
6643 
6644     Developer Note: fortran interface is not autogenerated as the f90
6645     interface defintion cannot be generated correctly [due to MatFactorInfo]
6646 
6647    References:
6648      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6649 @*/
6650 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6651 {
6652   PetscErrorCode ierr;
6653 
6654   PetscFunctionBegin;
6655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6656   PetscValidType(mat,1);
6657   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6658   PetscValidPointer(info,3);
6659   PetscValidPointer(fact,4);
6660   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6661   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6662   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6663   if (!(fact)->ops->iccfactorsymbolic) {
6664     MatSolverType spackage;
6665     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6666     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6667   }
6668   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6669   MatCheckPreallocated(mat,2);
6670 
6671   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6672   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6673   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6674   PetscFunctionReturn(0);
6675 }
6676 
6677 /*@C
6678    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6679    points to an array of valid matrices, they may be reused to store the new
6680    submatrices.
6681 
6682    Collective on Mat
6683 
6684    Input Parameters:
6685 +  mat - the matrix
6686 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6687 .  irow, icol - index sets of rows and columns to extract
6688 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6689 
6690    Output Parameter:
6691 .  submat - the array of submatrices
6692 
6693    Notes:
6694    MatCreateSubMatrices() can extract ONLY sequential submatrices
6695    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6696    to extract a parallel submatrix.
6697 
6698    Some matrix types place restrictions on the row and column
6699    indices, such as that they be sorted or that they be equal to each other.
6700 
6701    The index sets may not have duplicate entries.
6702 
6703    When extracting submatrices from a parallel matrix, each processor can
6704    form a different submatrix by setting the rows and columns of its
6705    individual index sets according to the local submatrix desired.
6706 
6707    When finished using the submatrices, the user should destroy
6708    them with MatDestroySubMatrices().
6709 
6710    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6711    original matrix has not changed from that last call to MatCreateSubMatrices().
6712 
6713    This routine creates the matrices in submat; you should NOT create them before
6714    calling it. It also allocates the array of matrix pointers submat.
6715 
6716    For BAIJ matrices the index sets must respect the block structure, that is if they
6717    request one row/column in a block, they must request all rows/columns that are in
6718    that block. For example, if the block size is 2 you cannot request just row 0 and
6719    column 0.
6720 
6721    Fortran Note:
6722    The Fortran interface is slightly different from that given below; it
6723    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6724 
6725    Level: advanced
6726 
6727 
6728 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6729 @*/
6730 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6731 {
6732   PetscErrorCode ierr;
6733   PetscInt       i;
6734   PetscBool      eq;
6735 
6736   PetscFunctionBegin;
6737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6738   PetscValidType(mat,1);
6739   if (n) {
6740     PetscValidPointer(irow,3);
6741     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6742     PetscValidPointer(icol,4);
6743     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6744   }
6745   PetscValidPointer(submat,6);
6746   if (n && scall == MAT_REUSE_MATRIX) {
6747     PetscValidPointer(*submat,6);
6748     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6749   }
6750   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6751   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6752   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6753   MatCheckPreallocated(mat,1);
6754 
6755   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6756   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6757   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6758   for (i=0; i<n; i++) {
6759     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6760     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6761     if (eq) {
6762       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6763     }
6764   }
6765   PetscFunctionReturn(0);
6766 }
6767 
6768 /*@C
6769    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6770 
6771    Collective on Mat
6772 
6773    Input Parameters:
6774 +  mat - the matrix
6775 .  n   - the number of submatrixes to be extracted
6776 .  irow, icol - index sets of rows and columns to extract
6777 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6778 
6779    Output Parameter:
6780 .  submat - the array of submatrices
6781 
6782    Level: advanced
6783 
6784 
6785 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6786 @*/
6787 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6788 {
6789   PetscErrorCode ierr;
6790   PetscInt       i;
6791   PetscBool      eq;
6792 
6793   PetscFunctionBegin;
6794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6795   PetscValidType(mat,1);
6796   if (n) {
6797     PetscValidPointer(irow,3);
6798     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6799     PetscValidPointer(icol,4);
6800     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6801   }
6802   PetscValidPointer(submat,6);
6803   if (n && scall == MAT_REUSE_MATRIX) {
6804     PetscValidPointer(*submat,6);
6805     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6806   }
6807   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6808   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6809   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6810   MatCheckPreallocated(mat,1);
6811 
6812   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6813   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6814   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6815   for (i=0; i<n; i++) {
6816     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6817     if (eq) {
6818       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6819     }
6820   }
6821   PetscFunctionReturn(0);
6822 }
6823 
6824 /*@C
6825    MatDestroyMatrices - Destroys an array of matrices.
6826 
6827    Collective on Mat
6828 
6829    Input Parameters:
6830 +  n - the number of local matrices
6831 -  mat - the matrices (note that this is a pointer to the array of matrices)
6832 
6833    Level: advanced
6834 
6835     Notes:
6836     Frees not only the matrices, but also the array that contains the matrices
6837            In Fortran will not free the array.
6838 
6839 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6840 @*/
6841 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6842 {
6843   PetscErrorCode ierr;
6844   PetscInt       i;
6845 
6846   PetscFunctionBegin;
6847   if (!*mat) PetscFunctionReturn(0);
6848   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6849   PetscValidPointer(mat,2);
6850 
6851   for (i=0; i<n; i++) {
6852     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6853   }
6854 
6855   /* memory is allocated even if n = 0 */
6856   ierr = PetscFree(*mat);CHKERRQ(ierr);
6857   PetscFunctionReturn(0);
6858 }
6859 
6860 /*@C
6861    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6862 
6863    Collective on Mat
6864 
6865    Input Parameters:
6866 +  n - the number of local matrices
6867 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6868                        sequence of MatCreateSubMatrices())
6869 
6870    Level: advanced
6871 
6872     Notes:
6873     Frees not only the matrices, but also the array that contains the matrices
6874            In Fortran will not free the array.
6875 
6876 .seealso: MatCreateSubMatrices()
6877 @*/
6878 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6879 {
6880   PetscErrorCode ierr;
6881   Mat            mat0;
6882 
6883   PetscFunctionBegin;
6884   if (!*mat) PetscFunctionReturn(0);
6885   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6886   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6887   PetscValidPointer(mat,2);
6888 
6889   mat0 = (*mat)[0];
6890   if (mat0 && mat0->ops->destroysubmatrices) {
6891     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6892   } else {
6893     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6894   }
6895   PetscFunctionReturn(0);
6896 }
6897 
6898 /*@C
6899    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6900 
6901    Collective on Mat
6902 
6903    Input Parameters:
6904 .  mat - the matrix
6905 
6906    Output Parameter:
6907 .  matstruct - the sequential matrix with the nonzero structure of mat
6908 
6909   Level: intermediate
6910 
6911 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6912 @*/
6913 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6914 {
6915   PetscErrorCode ierr;
6916 
6917   PetscFunctionBegin;
6918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6919   PetscValidPointer(matstruct,2);
6920 
6921   PetscValidType(mat,1);
6922   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6923   MatCheckPreallocated(mat,1);
6924 
6925   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6926   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6927   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6928   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6929   PetscFunctionReturn(0);
6930 }
6931 
6932 /*@C
6933    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6934 
6935    Collective on Mat
6936 
6937    Input Parameters:
6938 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6939                        sequence of MatGetSequentialNonzeroStructure())
6940 
6941    Level: advanced
6942 
6943     Notes:
6944     Frees not only the matrices, but also the array that contains the matrices
6945 
6946 .seealso: MatGetSeqNonzeroStructure()
6947 @*/
6948 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6949 {
6950   PetscErrorCode ierr;
6951 
6952   PetscFunctionBegin;
6953   PetscValidPointer(mat,1);
6954   ierr = MatDestroy(mat);CHKERRQ(ierr);
6955   PetscFunctionReturn(0);
6956 }
6957 
6958 /*@
6959    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6960    replaces the index sets by larger ones that represent submatrices with
6961    additional overlap.
6962 
6963    Collective on Mat
6964 
6965    Input Parameters:
6966 +  mat - the matrix
6967 .  n   - the number of index sets
6968 .  is  - the array of index sets (these index sets will changed during the call)
6969 -  ov  - the additional overlap requested
6970 
6971    Options Database:
6972 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6973 
6974    Level: developer
6975 
6976 
6977 .seealso: MatCreateSubMatrices()
6978 @*/
6979 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6980 {
6981   PetscErrorCode ierr;
6982 
6983   PetscFunctionBegin;
6984   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6985   PetscValidType(mat,1);
6986   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6987   if (n) {
6988     PetscValidPointer(is,3);
6989     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6990   }
6991   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6992   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6993   MatCheckPreallocated(mat,1);
6994 
6995   if (!ov) PetscFunctionReturn(0);
6996   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6997   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6998   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6999   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7000   PetscFunctionReturn(0);
7001 }
7002 
7003 
7004 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7005 
7006 /*@
7007    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7008    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7009    additional overlap.
7010 
7011    Collective on Mat
7012 
7013    Input Parameters:
7014 +  mat - the matrix
7015 .  n   - the number of index sets
7016 .  is  - the array of index sets (these index sets will changed during the call)
7017 -  ov  - the additional overlap requested
7018 
7019    Options Database:
7020 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7021 
7022    Level: developer
7023 
7024 
7025 .seealso: MatCreateSubMatrices()
7026 @*/
7027 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7028 {
7029   PetscInt       i;
7030   PetscErrorCode ierr;
7031 
7032   PetscFunctionBegin;
7033   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7034   PetscValidType(mat,1);
7035   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7036   if (n) {
7037     PetscValidPointer(is,3);
7038     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7039   }
7040   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7041   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7042   MatCheckPreallocated(mat,1);
7043   if (!ov) PetscFunctionReturn(0);
7044   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7045   for(i=0; i<n; i++){
7046 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7047   }
7048   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 
7053 
7054 
7055 /*@
7056    MatGetBlockSize - Returns the matrix block size.
7057 
7058    Not Collective
7059 
7060    Input Parameter:
7061 .  mat - the matrix
7062 
7063    Output Parameter:
7064 .  bs - block size
7065 
7066    Notes:
7067     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7068 
7069    If the block size has not been set yet this routine returns 1.
7070 
7071    Level: intermediate
7072 
7073 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7074 @*/
7075 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7076 {
7077   PetscFunctionBegin;
7078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7079   PetscValidIntPointer(bs,2);
7080   *bs = PetscAbs(mat->rmap->bs);
7081   PetscFunctionReturn(0);
7082 }
7083 
7084 /*@
7085    MatGetBlockSizes - Returns the matrix block row and column sizes.
7086 
7087    Not Collective
7088 
7089    Input Parameter:
7090 .  mat - the matrix
7091 
7092    Output Parameter:
7093 +  rbs - row block size
7094 -  cbs - column block size
7095 
7096    Notes:
7097     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7098     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7099 
7100    If a block size has not been set yet this routine returns 1.
7101 
7102    Level: intermediate
7103 
7104 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7105 @*/
7106 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7107 {
7108   PetscFunctionBegin;
7109   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7110   if (rbs) PetscValidIntPointer(rbs,2);
7111   if (cbs) PetscValidIntPointer(cbs,3);
7112   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7113   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7114   PetscFunctionReturn(0);
7115 }
7116 
7117 /*@
7118    MatSetBlockSize - Sets the matrix block size.
7119 
7120    Logically Collective on Mat
7121 
7122    Input Parameters:
7123 +  mat - the matrix
7124 -  bs - block size
7125 
7126    Notes:
7127     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7128     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7129 
7130     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7131     is compatible with the matrix local sizes.
7132 
7133    Level: intermediate
7134 
7135 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7136 @*/
7137 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7138 {
7139   PetscErrorCode ierr;
7140 
7141   PetscFunctionBegin;
7142   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7143   PetscValidLogicalCollectiveInt(mat,bs,2);
7144   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7145   PetscFunctionReturn(0);
7146 }
7147 
7148 /*@
7149    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7150 
7151    Logically Collective on Mat
7152 
7153    Input Parameters:
7154 +  mat - the matrix
7155 .  nblocks - the number of blocks on this process
7156 -  bsizes - the block sizes
7157 
7158    Notes:
7159     Currently used by PCVPBJACOBI for SeqAIJ matrices
7160 
7161    Level: intermediate
7162 
7163 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7164 @*/
7165 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7166 {
7167   PetscErrorCode ierr;
7168   PetscInt       i,ncnt = 0, nlocal;
7169 
7170   PetscFunctionBegin;
7171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7172   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7173   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7174   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7175   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);
7176   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7177   mat->nblocks = nblocks;
7178   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7179   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7180   PetscFunctionReturn(0);
7181 }
7182 
7183 /*@C
7184    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7185 
7186    Logically Collective on Mat
7187 
7188    Input Parameters:
7189 .  mat - the matrix
7190 
7191    Output Parameters:
7192 +  nblocks - the number of blocks on this process
7193 -  bsizes - the block sizes
7194 
7195    Notes: Currently not supported from Fortran
7196 
7197    Level: intermediate
7198 
7199 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7200 @*/
7201 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7202 {
7203   PetscFunctionBegin;
7204   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7205   *nblocks = mat->nblocks;
7206   *bsizes  = mat->bsizes;
7207   PetscFunctionReturn(0);
7208 }
7209 
7210 /*@
7211    MatSetBlockSizes - Sets the matrix block row and column sizes.
7212 
7213    Logically Collective on Mat
7214 
7215    Input Parameters:
7216 +  mat - the matrix
7217 .  rbs - row block size
7218 -  cbs - column block size
7219 
7220    Notes:
7221     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7222     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7223     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7224 
7225     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7226     are compatible with the matrix local sizes.
7227 
7228     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7229 
7230    Level: intermediate
7231 
7232 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7233 @*/
7234 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7235 {
7236   PetscErrorCode ierr;
7237 
7238   PetscFunctionBegin;
7239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7240   PetscValidLogicalCollectiveInt(mat,rbs,2);
7241   PetscValidLogicalCollectiveInt(mat,cbs,3);
7242   if (mat->ops->setblocksizes) {
7243     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7244   }
7245   if (mat->rmap->refcnt) {
7246     ISLocalToGlobalMapping l2g = NULL;
7247     PetscLayout            nmap = NULL;
7248 
7249     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7250     if (mat->rmap->mapping) {
7251       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7252     }
7253     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7254     mat->rmap = nmap;
7255     mat->rmap->mapping = l2g;
7256   }
7257   if (mat->cmap->refcnt) {
7258     ISLocalToGlobalMapping l2g = NULL;
7259     PetscLayout            nmap = NULL;
7260 
7261     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7262     if (mat->cmap->mapping) {
7263       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7264     }
7265     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7266     mat->cmap = nmap;
7267     mat->cmap->mapping = l2g;
7268   }
7269   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7270   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7271   PetscFunctionReturn(0);
7272 }
7273 
7274 /*@
7275    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7276 
7277    Logically Collective on Mat
7278 
7279    Input Parameters:
7280 +  mat - the matrix
7281 .  fromRow - matrix from which to copy row block size
7282 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7283 
7284    Level: developer
7285 
7286 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7287 @*/
7288 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7289 {
7290   PetscErrorCode ierr;
7291 
7292   PetscFunctionBegin;
7293   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7294   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7295   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7296   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7297   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7298   PetscFunctionReturn(0);
7299 }
7300 
7301 /*@
7302    MatResidual - Default routine to calculate the residual.
7303 
7304    Collective on Mat
7305 
7306    Input Parameters:
7307 +  mat - the matrix
7308 .  b   - the right-hand-side
7309 -  x   - the approximate solution
7310 
7311    Output Parameter:
7312 .  r - location to store the residual
7313 
7314    Level: developer
7315 
7316 .seealso: PCMGSetResidual()
7317 @*/
7318 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7319 {
7320   PetscErrorCode ierr;
7321 
7322   PetscFunctionBegin;
7323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7324   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7325   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7326   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7327   PetscValidType(mat,1);
7328   MatCheckPreallocated(mat,1);
7329   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7330   if (!mat->ops->residual) {
7331     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7332     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7333   } else {
7334     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7335   }
7336   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7337   PetscFunctionReturn(0);
7338 }
7339 
7340 /*@C
7341     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7342 
7343    Collective on Mat
7344 
7345     Input Parameters:
7346 +   mat - the matrix
7347 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7348 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7349 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7350                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7351                  always used.
7352 
7353     Output Parameters:
7354 +   n - number of rows in the (possibly compressed) matrix
7355 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7356 .   ja - the column indices
7357 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7358            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7359 
7360     Level: developer
7361 
7362     Notes:
7363     You CANNOT change any of the ia[] or ja[] values.
7364 
7365     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7366 
7367     Fortran Notes:
7368     In Fortran use
7369 $
7370 $      PetscInt ia(1), ja(1)
7371 $      PetscOffset iia, jja
7372 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7373 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7374 
7375      or
7376 $
7377 $    PetscInt, pointer :: ia(:),ja(:)
7378 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7379 $    ! Access the ith and jth entries via ia(i) and ja(j)
7380 
7381 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7382 @*/
7383 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7384 {
7385   PetscErrorCode ierr;
7386 
7387   PetscFunctionBegin;
7388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7389   PetscValidType(mat,1);
7390   PetscValidIntPointer(n,5);
7391   if (ia) PetscValidIntPointer(ia,6);
7392   if (ja) PetscValidIntPointer(ja,7);
7393   PetscValidIntPointer(done,8);
7394   MatCheckPreallocated(mat,1);
7395   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7396   else {
7397     *done = PETSC_TRUE;
7398     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7399     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7400     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7401   }
7402   PetscFunctionReturn(0);
7403 }
7404 
7405 /*@C
7406     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7407 
7408     Collective on Mat
7409 
7410     Input Parameters:
7411 +   mat - the matrix
7412 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7413 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7414                 symmetrized
7415 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7416                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7417                  always used.
7418 .   n - number of columns in the (possibly compressed) matrix
7419 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7420 -   ja - the row indices
7421 
7422     Output Parameters:
7423 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7424 
7425     Level: developer
7426 
7427 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7428 @*/
7429 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7430 {
7431   PetscErrorCode ierr;
7432 
7433   PetscFunctionBegin;
7434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7435   PetscValidType(mat,1);
7436   PetscValidIntPointer(n,4);
7437   if (ia) PetscValidIntPointer(ia,5);
7438   if (ja) PetscValidIntPointer(ja,6);
7439   PetscValidIntPointer(done,7);
7440   MatCheckPreallocated(mat,1);
7441   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7442   else {
7443     *done = PETSC_TRUE;
7444     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7445   }
7446   PetscFunctionReturn(0);
7447 }
7448 
7449 /*@C
7450     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7451     MatGetRowIJ().
7452 
7453     Collective on Mat
7454 
7455     Input Parameters:
7456 +   mat - the matrix
7457 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7458 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7459                 symmetrized
7460 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7461                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7462                  always used.
7463 .   n - size of (possibly compressed) matrix
7464 .   ia - the row pointers
7465 -   ja - the column indices
7466 
7467     Output Parameters:
7468 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7469 
7470     Note:
7471     This routine zeros out n, ia, and ja. This is to prevent accidental
7472     us of the array after it has been restored. If you pass NULL, it will
7473     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7474 
7475     Level: developer
7476 
7477 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7478 @*/
7479 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7480 {
7481   PetscErrorCode ierr;
7482 
7483   PetscFunctionBegin;
7484   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7485   PetscValidType(mat,1);
7486   if (ia) PetscValidIntPointer(ia,6);
7487   if (ja) PetscValidIntPointer(ja,7);
7488   PetscValidIntPointer(done,8);
7489   MatCheckPreallocated(mat,1);
7490 
7491   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7492   else {
7493     *done = PETSC_TRUE;
7494     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7495     if (n)  *n = 0;
7496     if (ia) *ia = NULL;
7497     if (ja) *ja = NULL;
7498   }
7499   PetscFunctionReturn(0);
7500 }
7501 
7502 /*@C
7503     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7504     MatGetColumnIJ().
7505 
7506     Collective on Mat
7507 
7508     Input Parameters:
7509 +   mat - the matrix
7510 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7511 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7512                 symmetrized
7513 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7514                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7515                  always used.
7516 
7517     Output Parameters:
7518 +   n - size of (possibly compressed) matrix
7519 .   ia - the column pointers
7520 .   ja - the row indices
7521 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7522 
7523     Level: developer
7524 
7525 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7526 @*/
7527 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7528 {
7529   PetscErrorCode ierr;
7530 
7531   PetscFunctionBegin;
7532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7533   PetscValidType(mat,1);
7534   if (ia) PetscValidIntPointer(ia,5);
7535   if (ja) PetscValidIntPointer(ja,6);
7536   PetscValidIntPointer(done,7);
7537   MatCheckPreallocated(mat,1);
7538 
7539   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7540   else {
7541     *done = PETSC_TRUE;
7542     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7543     if (n)  *n = 0;
7544     if (ia) *ia = NULL;
7545     if (ja) *ja = NULL;
7546   }
7547   PetscFunctionReturn(0);
7548 }
7549 
7550 /*@C
7551     MatColoringPatch -Used inside matrix coloring routines that
7552     use MatGetRowIJ() and/or MatGetColumnIJ().
7553 
7554     Collective on Mat
7555 
7556     Input Parameters:
7557 +   mat - the matrix
7558 .   ncolors - max color value
7559 .   n   - number of entries in colorarray
7560 -   colorarray - array indicating color for each column
7561 
7562     Output Parameters:
7563 .   iscoloring - coloring generated using colorarray information
7564 
7565     Level: developer
7566 
7567 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7568 
7569 @*/
7570 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7571 {
7572   PetscErrorCode ierr;
7573 
7574   PetscFunctionBegin;
7575   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7576   PetscValidType(mat,1);
7577   PetscValidIntPointer(colorarray,4);
7578   PetscValidPointer(iscoloring,5);
7579   MatCheckPreallocated(mat,1);
7580 
7581   if (!mat->ops->coloringpatch) {
7582     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7583   } else {
7584     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7585   }
7586   PetscFunctionReturn(0);
7587 }
7588 
7589 
7590 /*@
7591    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7592 
7593    Logically Collective on Mat
7594 
7595    Input Parameter:
7596 .  mat - the factored matrix to be reset
7597 
7598    Notes:
7599    This routine should be used only with factored matrices formed by in-place
7600    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7601    format).  This option can save memory, for example, when solving nonlinear
7602    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7603    ILU(0) preconditioner.
7604 
7605    Note that one can specify in-place ILU(0) factorization by calling
7606 .vb
7607      PCType(pc,PCILU);
7608      PCFactorSeUseInPlace(pc);
7609 .ve
7610    or by using the options -pc_type ilu -pc_factor_in_place
7611 
7612    In-place factorization ILU(0) can also be used as a local
7613    solver for the blocks within the block Jacobi or additive Schwarz
7614    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7615    for details on setting local solver options.
7616 
7617    Most users should employ the simplified KSP interface for linear solvers
7618    instead of working directly with matrix algebra routines such as this.
7619    See, e.g., KSPCreate().
7620 
7621    Level: developer
7622 
7623 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7624 
7625 @*/
7626 PetscErrorCode MatSetUnfactored(Mat mat)
7627 {
7628   PetscErrorCode ierr;
7629 
7630   PetscFunctionBegin;
7631   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7632   PetscValidType(mat,1);
7633   MatCheckPreallocated(mat,1);
7634   mat->factortype = MAT_FACTOR_NONE;
7635   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7636   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7637   PetscFunctionReturn(0);
7638 }
7639 
7640 /*MC
7641     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7642 
7643     Synopsis:
7644     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7645 
7646     Not collective
7647 
7648     Input Parameter:
7649 .   x - matrix
7650 
7651     Output Parameters:
7652 +   xx_v - the Fortran90 pointer to the array
7653 -   ierr - error code
7654 
7655     Example of Usage:
7656 .vb
7657       PetscScalar, pointer xx_v(:,:)
7658       ....
7659       call MatDenseGetArrayF90(x,xx_v,ierr)
7660       a = xx_v(3)
7661       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7662 .ve
7663 
7664     Level: advanced
7665 
7666 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7667 
7668 M*/
7669 
7670 /*MC
7671     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7672     accessed with MatDenseGetArrayF90().
7673 
7674     Synopsis:
7675     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7676 
7677     Not collective
7678 
7679     Input Parameters:
7680 +   x - matrix
7681 -   xx_v - the Fortran90 pointer to the array
7682 
7683     Output Parameter:
7684 .   ierr - error code
7685 
7686     Example of Usage:
7687 .vb
7688        PetscScalar, pointer xx_v(:,:)
7689        ....
7690        call MatDenseGetArrayF90(x,xx_v,ierr)
7691        a = xx_v(3)
7692        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7693 .ve
7694 
7695     Level: advanced
7696 
7697 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7698 
7699 M*/
7700 
7701 
7702 /*MC
7703     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7704 
7705     Synopsis:
7706     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7707 
7708     Not collective
7709 
7710     Input Parameter:
7711 .   x - matrix
7712 
7713     Output Parameters:
7714 +   xx_v - the Fortran90 pointer to the array
7715 -   ierr - error code
7716 
7717     Example of Usage:
7718 .vb
7719       PetscScalar, pointer xx_v(:)
7720       ....
7721       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7722       a = xx_v(3)
7723       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7724 .ve
7725 
7726     Level: advanced
7727 
7728 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7729 
7730 M*/
7731 
7732 /*MC
7733     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7734     accessed with MatSeqAIJGetArrayF90().
7735 
7736     Synopsis:
7737     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7738 
7739     Not collective
7740 
7741     Input Parameters:
7742 +   x - matrix
7743 -   xx_v - the Fortran90 pointer to the array
7744 
7745     Output Parameter:
7746 .   ierr - error code
7747 
7748     Example of Usage:
7749 .vb
7750        PetscScalar, pointer xx_v(:)
7751        ....
7752        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7753        a = xx_v(3)
7754        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7755 .ve
7756 
7757     Level: advanced
7758 
7759 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7760 
7761 M*/
7762 
7763 
7764 /*@
7765     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7766                       as the original matrix.
7767 
7768     Collective on Mat
7769 
7770     Input Parameters:
7771 +   mat - the original matrix
7772 .   isrow - parallel IS containing the rows this processor should obtain
7773 .   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.
7774 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7775 
7776     Output Parameter:
7777 .   newmat - the new submatrix, of the same type as the old
7778 
7779     Level: advanced
7780 
7781     Notes:
7782     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7783 
7784     Some matrix types place restrictions on the row and column indices, such
7785     as that they be sorted or that they be equal to each other.
7786 
7787     The index sets may not have duplicate entries.
7788 
7789       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7790    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7791    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7792    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7793    you are finished using it.
7794 
7795     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7796     the input matrix.
7797 
7798     If iscol is NULL then all columns are obtained (not supported in Fortran).
7799 
7800    Example usage:
7801    Consider the following 8x8 matrix with 34 non-zero values, that is
7802    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7803    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7804    as follows:
7805 
7806 .vb
7807             1  2  0  |  0  3  0  |  0  4
7808     Proc0   0  5  6  |  7  0  0  |  8  0
7809             9  0 10  | 11  0  0  | 12  0
7810     -------------------------------------
7811            13  0 14  | 15 16 17  |  0  0
7812     Proc1   0 18  0  | 19 20 21  |  0  0
7813             0  0  0  | 22 23  0  | 24  0
7814     -------------------------------------
7815     Proc2  25 26 27  |  0  0 28  | 29  0
7816            30  0  0  | 31 32 33  |  0 34
7817 .ve
7818 
7819     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7820 
7821 .vb
7822             2  0  |  0  3  0  |  0
7823     Proc0   5  6  |  7  0  0  |  8
7824     -------------------------------
7825     Proc1  18  0  | 19 20 21  |  0
7826     -------------------------------
7827     Proc2  26 27  |  0  0 28  | 29
7828             0  0  | 31 32 33  |  0
7829 .ve
7830 
7831 
7832 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
7833 @*/
7834 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7835 {
7836   PetscErrorCode ierr;
7837   PetscMPIInt    size;
7838   Mat            *local;
7839   IS             iscoltmp;
7840   PetscBool      flg;
7841 
7842   PetscFunctionBegin;
7843   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7844   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7845   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7846   PetscValidPointer(newmat,5);
7847   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7848   PetscValidType(mat,1);
7849   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7850   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7851 
7852   MatCheckPreallocated(mat,1);
7853   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7854 
7855   if (!iscol || isrow == iscol) {
7856     PetscBool   stride;
7857     PetscMPIInt grabentirematrix = 0,grab;
7858     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7859     if (stride) {
7860       PetscInt first,step,n,rstart,rend;
7861       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7862       if (step == 1) {
7863         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7864         if (rstart == first) {
7865           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7866           if (n == rend-rstart) {
7867             grabentirematrix = 1;
7868           }
7869         }
7870       }
7871     }
7872     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7873     if (grab) {
7874       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7875       if (cll == MAT_INITIAL_MATRIX) {
7876         *newmat = mat;
7877         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7878       }
7879       PetscFunctionReturn(0);
7880     }
7881   }
7882 
7883   if (!iscol) {
7884     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7885   } else {
7886     iscoltmp = iscol;
7887   }
7888 
7889   /* if original matrix is on just one processor then use submatrix generated */
7890   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7891     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7892     goto setproperties;
7893   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7894     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7895     *newmat = *local;
7896     ierr    = PetscFree(local);CHKERRQ(ierr);
7897     goto setproperties;
7898   } else if (!mat->ops->createsubmatrix) {
7899     /* Create a new matrix type that implements the operation using the full matrix */
7900     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7901     switch (cll) {
7902     case MAT_INITIAL_MATRIX:
7903       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7904       break;
7905     case MAT_REUSE_MATRIX:
7906       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7907       break;
7908     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7909     }
7910     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7911     goto setproperties;
7912   }
7913 
7914   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7915   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7916   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7917   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7918 
7919 setproperties:
7920   ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr);
7921   if (flg) {
7922     ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr);
7923   }
7924   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7925   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7926   PetscFunctionReturn(0);
7927 }
7928 
7929 /*@
7930    MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
7931 
7932    Not Collective
7933 
7934    Input Parameters:
7935 +  A - the matrix we wish to propagate options from
7936 -  B - the matrix we wish to propagate options to
7937 
7938    Level: beginner
7939 
7940    Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
7941 
7942 .seealso: MatSetOption()
7943 @*/
7944 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
7945 {
7946   PetscErrorCode ierr;
7947 
7948   PetscFunctionBegin;
7949   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7950   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
7951   if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
7952     ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr);
7953   }
7954   if (A->structurally_symmetric_set) {
7955     ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr);
7956   }
7957   if (A->hermitian_set) {
7958     ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr);
7959   }
7960   if (A->spd_set) {
7961     ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr);
7962   }
7963   if (A->symmetric_set) {
7964     ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr);
7965   }
7966   PetscFunctionReturn(0);
7967 }
7968 
7969 /*@
7970    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7971    used during the assembly process to store values that belong to
7972    other processors.
7973 
7974    Not Collective
7975 
7976    Input Parameters:
7977 +  mat   - the matrix
7978 .  size  - the initial size of the stash.
7979 -  bsize - the initial size of the block-stash(if used).
7980 
7981    Options Database Keys:
7982 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7983 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7984 
7985    Level: intermediate
7986 
7987    Notes:
7988      The block-stash is used for values set with MatSetValuesBlocked() while
7989      the stash is used for values set with MatSetValues()
7990 
7991      Run with the option -info and look for output of the form
7992      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7993      to determine the appropriate value, MM, to use for size and
7994      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7995      to determine the value, BMM to use for bsize
7996 
7997 
7998 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7999 
8000 @*/
8001 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8002 {
8003   PetscErrorCode ierr;
8004 
8005   PetscFunctionBegin;
8006   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8007   PetscValidType(mat,1);
8008   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8009   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8010   PetscFunctionReturn(0);
8011 }
8012 
8013 /*@
8014    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8015      the matrix
8016 
8017    Neighbor-wise Collective on Mat
8018 
8019    Input Parameters:
8020 +  mat   - the matrix
8021 .  x,y - the vectors
8022 -  w - where the result is stored
8023 
8024    Level: intermediate
8025 
8026    Notes:
8027     w may be the same vector as y.
8028 
8029     This allows one to use either the restriction or interpolation (its transpose)
8030     matrix to do the interpolation
8031 
8032 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8033 
8034 @*/
8035 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8036 {
8037   PetscErrorCode ierr;
8038   PetscInt       M,N,Ny;
8039 
8040   PetscFunctionBegin;
8041   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8042   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8043   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8044   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8045   PetscValidType(A,1);
8046   MatCheckPreallocated(A,1);
8047   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8048   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8049   if (M == Ny) {
8050     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8051   } else {
8052     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8053   }
8054   PetscFunctionReturn(0);
8055 }
8056 
8057 /*@
8058    MatInterpolate - y = A*x or A'*x depending on the shape of
8059      the matrix
8060 
8061    Neighbor-wise Collective on Mat
8062 
8063    Input Parameters:
8064 +  mat   - the matrix
8065 -  x,y - the vectors
8066 
8067    Level: intermediate
8068 
8069    Notes:
8070     This allows one to use either the restriction or interpolation (its transpose)
8071     matrix to do the interpolation
8072 
8073 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8074 
8075 @*/
8076 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8077 {
8078   PetscErrorCode ierr;
8079   PetscInt       M,N,Ny;
8080 
8081   PetscFunctionBegin;
8082   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8083   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8084   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8085   PetscValidType(A,1);
8086   MatCheckPreallocated(A,1);
8087   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8088   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8089   if (M == Ny) {
8090     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8091   } else {
8092     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8093   }
8094   PetscFunctionReturn(0);
8095 }
8096 
8097 /*@
8098    MatRestrict - y = A*x or A'*x
8099 
8100    Neighbor-wise Collective on Mat
8101 
8102    Input Parameters:
8103 +  mat   - the matrix
8104 -  x,y - the vectors
8105 
8106    Level: intermediate
8107 
8108    Notes:
8109     This allows one to use either the restriction or interpolation (its transpose)
8110     matrix to do the restriction
8111 
8112 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8113 
8114 @*/
8115 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8116 {
8117   PetscErrorCode ierr;
8118   PetscInt       M,N,Ny;
8119 
8120   PetscFunctionBegin;
8121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8122   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8123   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8124   PetscValidType(A,1);
8125   MatCheckPreallocated(A,1);
8126 
8127   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8128   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8129   if (M == Ny) {
8130     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8131   } else {
8132     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8133   }
8134   PetscFunctionReturn(0);
8135 }
8136 
8137 /*@
8138    MatGetNullSpace - retrieves the null space of a matrix.
8139 
8140    Logically Collective on Mat
8141 
8142    Input Parameters:
8143 +  mat - the matrix
8144 -  nullsp - the null space object
8145 
8146    Level: developer
8147 
8148 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8149 @*/
8150 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8151 {
8152   PetscFunctionBegin;
8153   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8154   PetscValidPointer(nullsp,2);
8155   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8156   PetscFunctionReturn(0);
8157 }
8158 
8159 /*@
8160    MatSetNullSpace - attaches a null space to a matrix.
8161 
8162    Logically Collective on Mat
8163 
8164    Input Parameters:
8165 +  mat - the matrix
8166 -  nullsp - the null space object
8167 
8168    Level: advanced
8169 
8170    Notes:
8171       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8172 
8173       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8174       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8175 
8176       You can remove the null space by calling this routine with an nullsp of NULL
8177 
8178 
8179       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8180    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).
8181    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
8182    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
8183    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).
8184 
8185       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8186 
8187     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
8188     routine also automatically calls MatSetTransposeNullSpace().
8189 
8190 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8191 @*/
8192 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8193 {
8194   PetscErrorCode ierr;
8195 
8196   PetscFunctionBegin;
8197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8198   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8199   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8200   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8201   mat->nullsp = nullsp;
8202   if (mat->symmetric_set && mat->symmetric) {
8203     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8204   }
8205   PetscFunctionReturn(0);
8206 }
8207 
8208 /*@
8209    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8210 
8211    Logically Collective on Mat
8212 
8213    Input Parameters:
8214 +  mat - the matrix
8215 -  nullsp - the null space object
8216 
8217    Level: developer
8218 
8219 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8220 @*/
8221 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8222 {
8223   PetscFunctionBegin;
8224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8225   PetscValidType(mat,1);
8226   PetscValidPointer(nullsp,2);
8227   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8228   PetscFunctionReturn(0);
8229 }
8230 
8231 /*@
8232    MatSetTransposeNullSpace - attaches a null space to a matrix.
8233 
8234    Logically Collective on Mat
8235 
8236    Input Parameters:
8237 +  mat - the matrix
8238 -  nullsp - the null space object
8239 
8240    Level: advanced
8241 
8242    Notes:
8243       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.
8244       You must also call MatSetNullSpace()
8245 
8246 
8247       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8248    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).
8249    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
8250    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
8251    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).
8252 
8253       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8254 
8255 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8256 @*/
8257 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8258 {
8259   PetscErrorCode ierr;
8260 
8261   PetscFunctionBegin;
8262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8263   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8264   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8265   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8266   mat->transnullsp = nullsp;
8267   PetscFunctionReturn(0);
8268 }
8269 
8270 /*@
8271    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8272         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8273 
8274    Logically Collective on Mat
8275 
8276    Input Parameters:
8277 +  mat - the matrix
8278 -  nullsp - the null space object
8279 
8280    Level: advanced
8281 
8282    Notes:
8283       Overwrites any previous near null space that may have been attached
8284 
8285       You can remove the null space by calling this routine with an nullsp of NULL
8286 
8287 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8288 @*/
8289 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8290 {
8291   PetscErrorCode ierr;
8292 
8293   PetscFunctionBegin;
8294   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8295   PetscValidType(mat,1);
8296   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8297   MatCheckPreallocated(mat,1);
8298   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8299   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8300   mat->nearnullsp = nullsp;
8301   PetscFunctionReturn(0);
8302 }
8303 
8304 /*@
8305    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8306 
8307    Not Collective
8308 
8309    Input Parameter:
8310 .  mat - the matrix
8311 
8312    Output Parameter:
8313 .  nullsp - the null space object, NULL if not set
8314 
8315    Level: developer
8316 
8317 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8318 @*/
8319 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8320 {
8321   PetscFunctionBegin;
8322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8323   PetscValidType(mat,1);
8324   PetscValidPointer(nullsp,2);
8325   MatCheckPreallocated(mat,1);
8326   *nullsp = mat->nearnullsp;
8327   PetscFunctionReturn(0);
8328 }
8329 
8330 /*@C
8331    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8332 
8333    Collective on Mat
8334 
8335    Input Parameters:
8336 +  mat - the matrix
8337 .  row - row/column permutation
8338 .  fill - expected fill factor >= 1.0
8339 -  level - level of fill, for ICC(k)
8340 
8341    Notes:
8342    Probably really in-place only when level of fill is zero, otherwise allocates
8343    new space to store factored matrix and deletes previous memory.
8344 
8345    Most users should employ the simplified KSP interface for linear solvers
8346    instead of working directly with matrix algebra routines such as this.
8347    See, e.g., KSPCreate().
8348 
8349    Level: developer
8350 
8351 
8352 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8353 
8354     Developer Note: fortran interface is not autogenerated as the f90
8355     interface defintion cannot be generated correctly [due to MatFactorInfo]
8356 
8357 @*/
8358 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8359 {
8360   PetscErrorCode ierr;
8361 
8362   PetscFunctionBegin;
8363   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8364   PetscValidType(mat,1);
8365   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8366   PetscValidPointer(info,3);
8367   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8368   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8369   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8370   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8371   MatCheckPreallocated(mat,1);
8372   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8373   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8374   PetscFunctionReturn(0);
8375 }
8376 
8377 /*@
8378    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8379          ghosted ones.
8380 
8381    Not Collective
8382 
8383    Input Parameters:
8384 +  mat - the matrix
8385 -  diag = the diagonal values, including ghost ones
8386 
8387    Level: developer
8388 
8389    Notes:
8390     Works only for MPIAIJ and MPIBAIJ matrices
8391 
8392 .seealso: MatDiagonalScale()
8393 @*/
8394 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8395 {
8396   PetscErrorCode ierr;
8397   PetscMPIInt    size;
8398 
8399   PetscFunctionBegin;
8400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8401   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8402   PetscValidType(mat,1);
8403 
8404   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8405   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8406   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8407   if (size == 1) {
8408     PetscInt n,m;
8409     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8410     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8411     if (m == n) {
8412       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8413     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8414   } else {
8415     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8416   }
8417   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8418   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8419   PetscFunctionReturn(0);
8420 }
8421 
8422 /*@
8423    MatGetInertia - Gets the inertia from a factored matrix
8424 
8425    Collective on Mat
8426 
8427    Input Parameter:
8428 .  mat - the matrix
8429 
8430    Output Parameters:
8431 +   nneg - number of negative eigenvalues
8432 .   nzero - number of zero eigenvalues
8433 -   npos - number of positive eigenvalues
8434 
8435    Level: advanced
8436 
8437    Notes:
8438     Matrix must have been factored by MatCholeskyFactor()
8439 
8440 
8441 @*/
8442 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8443 {
8444   PetscErrorCode ierr;
8445 
8446   PetscFunctionBegin;
8447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8448   PetscValidType(mat,1);
8449   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8450   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8451   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8452   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8453   PetscFunctionReturn(0);
8454 }
8455 
8456 /* ----------------------------------------------------------------*/
8457 /*@C
8458    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8459 
8460    Neighbor-wise Collective on Mats
8461 
8462    Input Parameters:
8463 +  mat - the factored matrix
8464 -  b - the right-hand-side vectors
8465 
8466    Output Parameter:
8467 .  x - the result vectors
8468 
8469    Notes:
8470    The vectors b and x cannot be the same.  I.e., one cannot
8471    call MatSolves(A,x,x).
8472 
8473    Notes:
8474    Most users should employ the simplified KSP interface for linear solvers
8475    instead of working directly with matrix algebra routines such as this.
8476    See, e.g., KSPCreate().
8477 
8478    Level: developer
8479 
8480 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8481 @*/
8482 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8483 {
8484   PetscErrorCode ierr;
8485 
8486   PetscFunctionBegin;
8487   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8488   PetscValidType(mat,1);
8489   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8490   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8491   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8492 
8493   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8494   MatCheckPreallocated(mat,1);
8495   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8496   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8497   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8498   PetscFunctionReturn(0);
8499 }
8500 
8501 /*@
8502    MatIsSymmetric - Test whether a matrix is symmetric
8503 
8504    Collective on Mat
8505 
8506    Input Parameter:
8507 +  A - the matrix to test
8508 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8509 
8510    Output Parameters:
8511 .  flg - the result
8512 
8513    Notes:
8514     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8515 
8516    Level: intermediate
8517 
8518 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8519 @*/
8520 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8521 {
8522   PetscErrorCode ierr;
8523 
8524   PetscFunctionBegin;
8525   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8526   PetscValidBoolPointer(flg,2);
8527 
8528   if (!A->symmetric_set) {
8529     if (!A->ops->issymmetric) {
8530       MatType mattype;
8531       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8532       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8533     }
8534     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8535     if (!tol) {
8536       ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr);
8537     }
8538   } else if (A->symmetric) {
8539     *flg = PETSC_TRUE;
8540   } else if (!tol) {
8541     *flg = PETSC_FALSE;
8542   } else {
8543     if (!A->ops->issymmetric) {
8544       MatType mattype;
8545       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8546       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8547     }
8548     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8549   }
8550   PetscFunctionReturn(0);
8551 }
8552 
8553 /*@
8554    MatIsHermitian - Test whether a matrix is Hermitian
8555 
8556    Collective on Mat
8557 
8558    Input Parameter:
8559 +  A - the matrix to test
8560 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8561 
8562    Output Parameters:
8563 .  flg - the result
8564 
8565    Level: intermediate
8566 
8567 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8568           MatIsSymmetricKnown(), MatIsSymmetric()
8569 @*/
8570 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8571 {
8572   PetscErrorCode ierr;
8573 
8574   PetscFunctionBegin;
8575   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8576   PetscValidBoolPointer(flg,2);
8577 
8578   if (!A->hermitian_set) {
8579     if (!A->ops->ishermitian) {
8580       MatType mattype;
8581       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8582       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8583     }
8584     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8585     if (!tol) {
8586       ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr);
8587     }
8588   } else if (A->hermitian) {
8589     *flg = PETSC_TRUE;
8590   } else if (!tol) {
8591     *flg = PETSC_FALSE;
8592   } else {
8593     if (!A->ops->ishermitian) {
8594       MatType mattype;
8595       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8596       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8597     }
8598     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8599   }
8600   PetscFunctionReturn(0);
8601 }
8602 
8603 /*@
8604    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8605 
8606    Not Collective
8607 
8608    Input Parameter:
8609 .  A - the matrix to check
8610 
8611    Output Parameters:
8612 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8613 -  flg - the result
8614 
8615    Level: advanced
8616 
8617    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8618          if you want it explicitly checked
8619 
8620 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8621 @*/
8622 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8623 {
8624   PetscFunctionBegin;
8625   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8626   PetscValidPointer(set,2);
8627   PetscValidBoolPointer(flg,3);
8628   if (A->symmetric_set) {
8629     *set = PETSC_TRUE;
8630     *flg = A->symmetric;
8631   } else {
8632     *set = PETSC_FALSE;
8633   }
8634   PetscFunctionReturn(0);
8635 }
8636 
8637 /*@
8638    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8639 
8640    Not Collective
8641 
8642    Input Parameter:
8643 .  A - the matrix to check
8644 
8645    Output Parameters:
8646 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8647 -  flg - the result
8648 
8649    Level: advanced
8650 
8651    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8652          if you want it explicitly checked
8653 
8654 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8655 @*/
8656 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8657 {
8658   PetscFunctionBegin;
8659   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8660   PetscValidPointer(set,2);
8661   PetscValidBoolPointer(flg,3);
8662   if (A->hermitian_set) {
8663     *set = PETSC_TRUE;
8664     *flg = A->hermitian;
8665   } else {
8666     *set = PETSC_FALSE;
8667   }
8668   PetscFunctionReturn(0);
8669 }
8670 
8671 /*@
8672    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8673 
8674    Collective on Mat
8675 
8676    Input Parameter:
8677 .  A - the matrix to test
8678 
8679    Output Parameters:
8680 .  flg - the result
8681 
8682    Level: intermediate
8683 
8684 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8685 @*/
8686 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8687 {
8688   PetscErrorCode ierr;
8689 
8690   PetscFunctionBegin;
8691   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8692   PetscValidBoolPointer(flg,2);
8693   if (!A->structurally_symmetric_set) {
8694     if (!A->ops->isstructurallysymmetric) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name);
8695     ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr);
8696     ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr);
8697   } else *flg = A->structurally_symmetric;
8698   PetscFunctionReturn(0);
8699 }
8700 
8701 /*@
8702    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8703        to be communicated to other processors during the MatAssemblyBegin/End() process
8704 
8705     Not collective
8706 
8707    Input Parameter:
8708 .   vec - the vector
8709 
8710    Output Parameters:
8711 +   nstash   - the size of the stash
8712 .   reallocs - the number of additional mallocs incurred.
8713 .   bnstash   - the size of the block stash
8714 -   breallocs - the number of additional mallocs incurred.in the block stash
8715 
8716    Level: advanced
8717 
8718 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8719 
8720 @*/
8721 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8722 {
8723   PetscErrorCode ierr;
8724 
8725   PetscFunctionBegin;
8726   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8727   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8728   PetscFunctionReturn(0);
8729 }
8730 
8731 /*@C
8732    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8733      parallel layout
8734 
8735    Collective on Mat
8736 
8737    Input Parameter:
8738 .  mat - the matrix
8739 
8740    Output Parameter:
8741 +   right - (optional) vector that the matrix can be multiplied against
8742 -   left - (optional) vector that the matrix vector product can be stored in
8743 
8744    Notes:
8745     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().
8746 
8747   Notes:
8748     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8749 
8750   Level: advanced
8751 
8752 .seealso: MatCreate(), VecDestroy()
8753 @*/
8754 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8755 {
8756   PetscErrorCode ierr;
8757 
8758   PetscFunctionBegin;
8759   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8760   PetscValidType(mat,1);
8761   if (mat->ops->getvecs) {
8762     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8763   } else {
8764     PetscInt rbs,cbs;
8765     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8766     if (right) {
8767       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8768       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8769       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8770       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8771       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8772       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8773     }
8774     if (left) {
8775       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8776       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8777       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8778       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8779       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8780       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8781     }
8782   }
8783   PetscFunctionReturn(0);
8784 }
8785 
8786 /*@C
8787    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8788      with default values.
8789 
8790    Not Collective
8791 
8792    Input Parameters:
8793 .    info - the MatFactorInfo data structure
8794 
8795 
8796    Notes:
8797     The solvers are generally used through the KSP and PC objects, for example
8798           PCLU, PCILU, PCCHOLESKY, PCICC
8799 
8800    Level: developer
8801 
8802 .seealso: MatFactorInfo
8803 
8804     Developer Note: fortran interface is not autogenerated as the f90
8805     interface defintion cannot be generated correctly [due to MatFactorInfo]
8806 
8807 @*/
8808 
8809 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8810 {
8811   PetscErrorCode ierr;
8812 
8813   PetscFunctionBegin;
8814   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8815   PetscFunctionReturn(0);
8816 }
8817 
8818 /*@
8819    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8820 
8821    Collective on Mat
8822 
8823    Input Parameters:
8824 +  mat - the factored matrix
8825 -  is - the index set defining the Schur indices (0-based)
8826 
8827    Notes:
8828     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8829 
8830    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8831 
8832    Level: developer
8833 
8834 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8835           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8836 
8837 @*/
8838 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8839 {
8840   PetscErrorCode ierr,(*f)(Mat,IS);
8841 
8842   PetscFunctionBegin;
8843   PetscValidType(mat,1);
8844   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8845   PetscValidType(is,2);
8846   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8847   PetscCheckSameComm(mat,1,is,2);
8848   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8849   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8850   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");
8851   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8852   ierr = (*f)(mat,is);CHKERRQ(ierr);
8853   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8854   PetscFunctionReturn(0);
8855 }
8856 
8857 /*@
8858   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8859 
8860    Logically Collective on Mat
8861 
8862    Input Parameters:
8863 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8864 .  S - location where to return the Schur complement, can be NULL
8865 -  status - the status of the Schur complement matrix, can be NULL
8866 
8867    Notes:
8868    You must call MatFactorSetSchurIS() before calling this routine.
8869 
8870    The routine provides a copy of the Schur matrix stored within the solver data structures.
8871    The caller must destroy the object when it is no longer needed.
8872    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8873 
8874    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)
8875 
8876    Developer Notes:
8877     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8878    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8879 
8880    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8881 
8882    Level: advanced
8883 
8884    References:
8885 
8886 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8887 @*/
8888 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8889 {
8890   PetscErrorCode ierr;
8891 
8892   PetscFunctionBegin;
8893   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8894   if (S) PetscValidPointer(S,2);
8895   if (status) PetscValidPointer(status,3);
8896   if (S) {
8897     PetscErrorCode (*f)(Mat,Mat*);
8898 
8899     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8900     if (f) {
8901       ierr = (*f)(F,S);CHKERRQ(ierr);
8902     } else {
8903       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8904     }
8905   }
8906   if (status) *status = F->schur_status;
8907   PetscFunctionReturn(0);
8908 }
8909 
8910 /*@
8911   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8912 
8913    Logically Collective on Mat
8914 
8915    Input Parameters:
8916 +  F - the factored matrix obtained by calling MatGetFactor()
8917 .  *S - location where to return the Schur complement, can be NULL
8918 -  status - the status of the Schur complement matrix, can be NULL
8919 
8920    Notes:
8921    You must call MatFactorSetSchurIS() before calling this routine.
8922 
8923    Schur complement mode is currently implemented for sequential matrices.
8924    The routine returns a the Schur Complement stored within the data strutures of the solver.
8925    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8926    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8927 
8928    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8929 
8930    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8931 
8932    Level: advanced
8933 
8934    References:
8935 
8936 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8937 @*/
8938 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8939 {
8940   PetscFunctionBegin;
8941   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8942   if (S) PetscValidPointer(S,2);
8943   if (status) PetscValidPointer(status,3);
8944   if (S) *S = F->schur;
8945   if (status) *status = F->schur_status;
8946   PetscFunctionReturn(0);
8947 }
8948 
8949 /*@
8950   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8951 
8952    Logically Collective on Mat
8953 
8954    Input Parameters:
8955 +  F - the factored matrix obtained by calling MatGetFactor()
8956 .  *S - location where the Schur complement is stored
8957 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8958 
8959    Notes:
8960 
8961    Level: advanced
8962 
8963    References:
8964 
8965 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8966 @*/
8967 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8968 {
8969   PetscErrorCode ierr;
8970 
8971   PetscFunctionBegin;
8972   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8973   if (S) {
8974     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8975     *S = NULL;
8976   }
8977   F->schur_status = status;
8978   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8979   PetscFunctionReturn(0);
8980 }
8981 
8982 /*@
8983   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8984 
8985    Logically Collective on Mat
8986 
8987    Input Parameters:
8988 +  F - the factored matrix obtained by calling MatGetFactor()
8989 .  rhs - location where the right hand side of the Schur complement system is stored
8990 -  sol - location where the solution of the Schur complement system has to be returned
8991 
8992    Notes:
8993    The sizes of the vectors should match the size of the Schur complement
8994 
8995    Must be called after MatFactorSetSchurIS()
8996 
8997    Level: advanced
8998 
8999    References:
9000 
9001 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9002 @*/
9003 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9004 {
9005   PetscErrorCode ierr;
9006 
9007   PetscFunctionBegin;
9008   PetscValidType(F,1);
9009   PetscValidType(rhs,2);
9010   PetscValidType(sol,3);
9011   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9012   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9013   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9014   PetscCheckSameComm(F,1,rhs,2);
9015   PetscCheckSameComm(F,1,sol,3);
9016   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9017   switch (F->schur_status) {
9018   case MAT_FACTOR_SCHUR_FACTORED:
9019     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9020     break;
9021   case MAT_FACTOR_SCHUR_INVERTED:
9022     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9023     break;
9024   default:
9025     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9026     break;
9027   }
9028   PetscFunctionReturn(0);
9029 }
9030 
9031 /*@
9032   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9033 
9034    Logically Collective on Mat
9035 
9036    Input Parameters:
9037 +  F - the factored matrix obtained by calling MatGetFactor()
9038 .  rhs - location where the right hand side of the Schur complement system is stored
9039 -  sol - location where the solution of the Schur complement system has to be returned
9040 
9041    Notes:
9042    The sizes of the vectors should match the size of the Schur complement
9043 
9044    Must be called after MatFactorSetSchurIS()
9045 
9046    Level: advanced
9047 
9048    References:
9049 
9050 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9051 @*/
9052 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9053 {
9054   PetscErrorCode ierr;
9055 
9056   PetscFunctionBegin;
9057   PetscValidType(F,1);
9058   PetscValidType(rhs,2);
9059   PetscValidType(sol,3);
9060   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9061   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9062   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9063   PetscCheckSameComm(F,1,rhs,2);
9064   PetscCheckSameComm(F,1,sol,3);
9065   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9066   switch (F->schur_status) {
9067   case MAT_FACTOR_SCHUR_FACTORED:
9068     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9069     break;
9070   case MAT_FACTOR_SCHUR_INVERTED:
9071     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9072     break;
9073   default:
9074     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9075     break;
9076   }
9077   PetscFunctionReturn(0);
9078 }
9079 
9080 /*@
9081   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9082 
9083    Logically Collective on Mat
9084 
9085    Input Parameters:
9086 .  F - the factored matrix obtained by calling MatGetFactor()
9087 
9088    Notes:
9089     Must be called after MatFactorSetSchurIS().
9090 
9091    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9092 
9093    Level: advanced
9094 
9095    References:
9096 
9097 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9098 @*/
9099 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9100 {
9101   PetscErrorCode ierr;
9102 
9103   PetscFunctionBegin;
9104   PetscValidType(F,1);
9105   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9106   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9107   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9108   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9109   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9110   PetscFunctionReturn(0);
9111 }
9112 
9113 /*@
9114   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9115 
9116    Logically Collective on Mat
9117 
9118    Input Parameters:
9119 .  F - the factored matrix obtained by calling MatGetFactor()
9120 
9121    Notes:
9122     Must be called after MatFactorSetSchurIS().
9123 
9124    Level: advanced
9125 
9126    References:
9127 
9128 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9129 @*/
9130 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9131 {
9132   PetscErrorCode ierr;
9133 
9134   PetscFunctionBegin;
9135   PetscValidType(F,1);
9136   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9137   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9138   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9139   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9140   PetscFunctionReturn(0);
9141 }
9142 
9143 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9144 {
9145   Mat            AP;
9146   PetscErrorCode ierr;
9147 
9148   PetscFunctionBegin;
9149   ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr);
9150   ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr);
9151   ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr);
9152   ierr = MatDestroy(&AP);CHKERRQ(ierr);
9153   PetscFunctionReturn(0);
9154 }
9155 
9156 /*@
9157    MatPtAP - Creates the matrix product C = P^T * A * P
9158 
9159    Neighbor-wise Collective on Mat
9160 
9161    Input Parameters:
9162 +  A - the matrix
9163 .  P - the projection matrix
9164 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9165 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9166           if the result is a dense matrix this is irrelevent
9167 
9168    Output Parameters:
9169 .  C - the product matrix
9170 
9171    Notes:
9172    C will be created and must be destroyed by the user with MatDestroy().
9173 
9174    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9175 
9176    Level: intermediate
9177 
9178 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9179 @*/
9180 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9181 {
9182   PetscErrorCode ierr;
9183   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9184   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9185   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9186   PetscBool      sametype;
9187 
9188   PetscFunctionBegin;
9189   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9190   PetscValidType(A,1);
9191   MatCheckPreallocated(A,1);
9192   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9193   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9194   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9195   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9196   PetscValidType(P,2);
9197   MatCheckPreallocated(P,2);
9198   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9199   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9200 
9201   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);
9202   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);
9203   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9204   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9205 
9206   if (scall == MAT_REUSE_MATRIX) {
9207     PetscValidPointer(*C,5);
9208     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9209 
9210     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9211     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9212     if ((*C)->ops->ptapnumeric) {
9213       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9214     } else {
9215       ierr = MatPtAP_Basic(A,P,scall,fill,C);
9216     }
9217     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9218     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9219     PetscFunctionReturn(0);
9220   }
9221 
9222   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9223   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9224 
9225   fA = A->ops->ptap;
9226   fP = P->ops->ptap;
9227   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9228   if (fP == fA && sametype) {
9229     ptap = fA;
9230   } else {
9231     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9232     char ptapname[256];
9233     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9234     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9235     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9236     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9237     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9238     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9239   }
9240 
9241   if (!ptap) ptap = MatPtAP_Basic;
9242   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9243   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9244   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9245   if (A->symmetric_set && A->symmetric) {
9246     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9247   }
9248   PetscFunctionReturn(0);
9249 }
9250 
9251 /*@
9252    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9253 
9254    Neighbor-wise Collective on Mat
9255 
9256    Input Parameters:
9257 +  A - the matrix
9258 -  P - the projection matrix
9259 
9260    Output Parameters:
9261 .  C - the product matrix
9262 
9263    Notes:
9264    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9265    the user using MatDeatroy().
9266 
9267    This routine is currently only implemented for pairs of AIJ matrices and classes
9268    which inherit from AIJ.  C will be of type MATAIJ.
9269 
9270    Level: intermediate
9271 
9272 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9273 @*/
9274 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9275 {
9276   PetscErrorCode ierr;
9277 
9278   PetscFunctionBegin;
9279   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9280   PetscValidType(A,1);
9281   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9282   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9283   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9284   PetscValidType(P,2);
9285   MatCheckPreallocated(P,2);
9286   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9287   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9288   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9289   PetscValidType(C,3);
9290   MatCheckPreallocated(C,3);
9291   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9292   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);
9293   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);
9294   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);
9295   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);
9296   MatCheckPreallocated(A,1);
9297 
9298   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9299   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9300   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9301   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9302   PetscFunctionReturn(0);
9303 }
9304 
9305 /*@
9306    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9307 
9308    Neighbor-wise Collective on Mat
9309 
9310    Input Parameters:
9311 +  A - the matrix
9312 -  P - the projection matrix
9313 
9314    Output Parameters:
9315 .  C - the (i,j) structure of the product matrix
9316 
9317    Notes:
9318    C will be created and must be destroyed by the user with MatDestroy().
9319 
9320    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9321    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9322    this (i,j) structure by calling MatPtAPNumeric().
9323 
9324    Level: intermediate
9325 
9326 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9327 @*/
9328 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9329 {
9330   PetscErrorCode ierr;
9331 
9332   PetscFunctionBegin;
9333   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9334   PetscValidType(A,1);
9335   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9336   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9337   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9338   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9339   PetscValidType(P,2);
9340   MatCheckPreallocated(P,2);
9341   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9342   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9343   PetscValidPointer(C,3);
9344 
9345   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);
9346   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);
9347   MatCheckPreallocated(A,1);
9348 
9349   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9350   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9351   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9352   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9353 
9354   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9355   PetscFunctionReturn(0);
9356 }
9357 
9358 /*@
9359    MatRARt - Creates the matrix product C = R * A * R^T
9360 
9361    Neighbor-wise Collective on Mat
9362 
9363    Input Parameters:
9364 +  A - the matrix
9365 .  R - the projection matrix
9366 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9367 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9368           if the result is a dense matrix this is irrelevent
9369 
9370    Output Parameters:
9371 .  C - the product matrix
9372 
9373    Notes:
9374    C will be created and must be destroyed by the user with MatDestroy().
9375 
9376    This routine is currently only implemented for pairs of AIJ matrices and classes
9377    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9378    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9379    We recommend using MatPtAP().
9380 
9381    Level: intermediate
9382 
9383 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9384 @*/
9385 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9386 {
9387   PetscErrorCode ierr;
9388 
9389   PetscFunctionBegin;
9390   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9391   PetscValidType(A,1);
9392   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9393   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9394   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9395   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9396   PetscValidType(R,2);
9397   MatCheckPreallocated(R,2);
9398   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9399   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9400   PetscValidPointer(C,3);
9401   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);
9402 
9403   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9404   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9405   MatCheckPreallocated(A,1);
9406 
9407   if (!A->ops->rart) {
9408     Mat Rt;
9409     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9410     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9411     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9412     PetscFunctionReturn(0);
9413   }
9414   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9415   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9416   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9417   PetscFunctionReturn(0);
9418 }
9419 
9420 /*@
9421    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9422 
9423    Neighbor-wise Collective on Mat
9424 
9425    Input Parameters:
9426 +  A - the matrix
9427 -  R - the projection matrix
9428 
9429    Output Parameters:
9430 .  C - the product matrix
9431 
9432    Notes:
9433    C must have been created by calling MatRARtSymbolic and must be destroyed by
9434    the user using MatDestroy().
9435 
9436    This routine is currently only implemented for pairs of AIJ matrices and classes
9437    which inherit from AIJ.  C will be of type MATAIJ.
9438 
9439    Level: intermediate
9440 
9441 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9442 @*/
9443 PetscErrorCode MatRARtNumeric(Mat A,Mat R,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   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9453   PetscValidType(R,2);
9454   MatCheckPreallocated(R,2);
9455   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9456   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9457   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9458   PetscValidType(C,3);
9459   MatCheckPreallocated(C,3);
9460   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9461   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);
9462   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);
9463   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);
9464   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);
9465   MatCheckPreallocated(A,1);
9466 
9467   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9468   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9469   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9470   PetscFunctionReturn(0);
9471 }
9472 
9473 /*@
9474    MatRARtSymbolic - Creates the (i,j) structure of 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 
9482    Output Parameters:
9483 .  C - the (i,j) structure of the product matrix
9484 
9485    Notes:
9486    C will be created and must be destroyed by the user with MatDestroy().
9487 
9488    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9489    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9490    this (i,j) structure by calling MatRARtNumeric().
9491 
9492    Level: intermediate
9493 
9494 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9495 @*/
9496 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9497 {
9498   PetscErrorCode ierr;
9499 
9500   PetscFunctionBegin;
9501   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9502   PetscValidType(A,1);
9503   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9504   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9505   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9506   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9507   PetscValidType(R,2);
9508   MatCheckPreallocated(R,2);
9509   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9510   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9511   PetscValidPointer(C,3);
9512 
9513   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);
9514   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);
9515   MatCheckPreallocated(A,1);
9516   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9517   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9518   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9519 
9520   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9521   PetscFunctionReturn(0);
9522 }
9523 
9524 /*@
9525    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9526 
9527    Neighbor-wise Collective on Mat
9528 
9529    Input Parameters:
9530 +  A - the left matrix
9531 .  B - the right matrix
9532 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9533 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9534           if the result is a dense matrix this is irrelevent
9535 
9536    Output Parameters:
9537 .  C - the product matrix
9538 
9539    Notes:
9540    Unless scall is MAT_REUSE_MATRIX C will be created.
9541 
9542    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
9543    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9544 
9545    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9546    actually needed.
9547 
9548    If you have many matrices with the same non-zero structure to multiply, you
9549    should either
9550 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9551 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9552    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
9553    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9554 
9555    Level: intermediate
9556 
9557 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9558 @*/
9559 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9560 {
9561   PetscErrorCode ierr;
9562   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9563   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9564   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9565   Mat            T;
9566   PetscBool      istrans;
9567 
9568   PetscFunctionBegin;
9569   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9570   PetscValidType(A,1);
9571   MatCheckPreallocated(A,1);
9572   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9573   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9574   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9575   PetscValidType(B,2);
9576   MatCheckPreallocated(B,2);
9577   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9578   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9579   PetscValidPointer(C,3);
9580   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9581   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);
9582   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9583   if (istrans) {
9584     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9585     ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9586     PetscFunctionReturn(0);
9587   } else {
9588     ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9589     if (istrans) {
9590       ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9591       ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr);
9592       PetscFunctionReturn(0);
9593     }
9594   }
9595   if (scall == MAT_REUSE_MATRIX) {
9596     PetscValidPointer(*C,5);
9597     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9598     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9599     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9600     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9601     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9602     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9603     PetscFunctionReturn(0);
9604   }
9605   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9606   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9607 
9608   fA = A->ops->matmult;
9609   fB = B->ops->matmult;
9610   if (fB == fA && fB) mult = fB;
9611   else {
9612     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9613     char multname[256];
9614     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9615     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9616     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9617     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9618     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9619     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9620     if (!mult) {
9621       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr);
9622     }
9623     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);
9624   }
9625   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9626   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9627   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9628   PetscFunctionReturn(0);
9629 }
9630 
9631 /*@
9632    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9633    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9634 
9635    Neighbor-wise Collective on Mat
9636 
9637    Input Parameters:
9638 +  A - the left matrix
9639 .  B - the right matrix
9640 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9641       if C is a dense matrix this is irrelevent
9642 
9643    Output Parameters:
9644 .  C - the product matrix
9645 
9646    Notes:
9647    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9648    actually needed.
9649 
9650    This routine is currently implemented for
9651     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9652     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9653     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9654 
9655    Level: intermediate
9656 
9657    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9658      We should incorporate them into PETSc.
9659 
9660 .seealso: MatMatMult(), MatMatMultNumeric()
9661 @*/
9662 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9663 {
9664   Mat            T = NULL;
9665   PetscBool      istrans;
9666   PetscErrorCode ierr;
9667   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9668   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9669   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9670 
9671   PetscFunctionBegin;
9672   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9673   PetscValidType(A,1);
9674   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9675   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9676 
9677   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9678   PetscValidType(B,2);
9679   MatCheckPreallocated(B,2);
9680   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9681   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9682   PetscValidPointer(C,3);
9683 
9684   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);
9685   if (fill == PETSC_DEFAULT) fill = 2.0;
9686   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9687   MatCheckPreallocated(A,1);
9688 
9689   Asymbolic = A->ops->matmultsymbolic;
9690   Bsymbolic = B->ops->matmultsymbolic;
9691   if (Asymbolic == Bsymbolic && Asymbolic) symbolic = Bsymbolic;
9692   else { /* dispatch based on the type of A and B */
9693     char symbolicname[256];
9694     ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9695     if (!istrans) {
9696       ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9697       ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9698       ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9699     } else {
9700       ierr = PetscStrncpy(symbolicname,"MatTransposeMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9701       ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9702       ierr = PetscStrlcat(symbolicname,((PetscObject)T)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9703       ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9704     }
9705     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9706     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9707     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9708     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);
9709   }
9710   ierr = PetscLogEventBegin(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9711   *C = NULL;
9712   ierr = (*symbolic)(!T ? A : T,B,fill,C);CHKERRQ(ierr);
9713   ierr = PetscLogEventEnd(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9714   PetscFunctionReturn(0);
9715 }
9716 
9717 /*@
9718    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9719    Call this routine after first calling MatMatMultSymbolic().
9720 
9721    Neighbor-wise Collective on Mat
9722 
9723    Input Parameters:
9724 +  A - the left matrix
9725 -  B - the right matrix
9726 
9727    Output Parameters:
9728 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9729 
9730    Notes:
9731    C must have been created with MatMatMultSymbolic().
9732 
9733    This routine is currently implemented for
9734     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9735     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9736     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9737 
9738    Level: intermediate
9739 
9740 .seealso: MatMatMult(), MatMatMultSymbolic()
9741 @*/
9742 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9743 {
9744   PetscErrorCode ierr;
9745 
9746   PetscFunctionBegin;
9747   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
9748   PetscFunctionReturn(0);
9749 }
9750 
9751 /*@
9752    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9753 
9754    Neighbor-wise Collective on Mat
9755 
9756    Input Parameters:
9757 +  A - the left matrix
9758 .  B - the right matrix
9759 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9760 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9761 
9762    Output Parameters:
9763 .  C - the product matrix
9764 
9765    Notes:
9766    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9767 
9768    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9769 
9770   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9771    actually needed.
9772 
9773    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9774    and for pairs of MPIDense matrices.
9775 
9776    Options Database Keys:
9777 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9778                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9779                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9780 
9781    Level: intermediate
9782 
9783 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9784 @*/
9785 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9786 {
9787   PetscErrorCode ierr;
9788   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9789   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9790   Mat            T;
9791   PetscBool      istrans;
9792 
9793   PetscFunctionBegin;
9794   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9795   PetscValidType(A,1);
9796   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9797   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9798   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9799   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9800   PetscValidType(B,2);
9801   MatCheckPreallocated(B,2);
9802   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9803   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9804   PetscValidPointer(C,3);
9805   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);
9806   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9807   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9808   MatCheckPreallocated(A,1);
9809 
9810   ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr);
9811   if (istrans) {
9812     ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr);
9813     ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr);
9814     PetscFunctionReturn(0);
9815   }
9816   fA = A->ops->mattransposemult;
9817   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9818   fB = B->ops->mattransposemult;
9819   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9820   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);
9821 
9822   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9823   if (scall == MAT_INITIAL_MATRIX) {
9824     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9825     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9826     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9827   }
9828   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9829   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9830   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9831   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9832   PetscFunctionReturn(0);
9833 }
9834 
9835 /*@
9836    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9837 
9838    Neighbor-wise Collective on Mat
9839 
9840    Input Parameters:
9841 +  A - the left matrix
9842 .  B - the right matrix
9843 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9844 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9845 
9846    Output Parameters:
9847 .  C - the product matrix
9848 
9849    Notes:
9850    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9851 
9852    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9853 
9854   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9855    actually needed.
9856 
9857    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9858    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9859 
9860    Level: intermediate
9861 
9862 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9863 @*/
9864 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9865 {
9866   PetscErrorCode ierr;
9867   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9868   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9869   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9870   Mat            T;
9871   PetscBool      flg;
9872 
9873   PetscFunctionBegin;
9874   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9875   PetscValidType(A,1);
9876   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9877   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9878   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9879   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9880   PetscValidType(B,2);
9881   MatCheckPreallocated(B,2);
9882   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9883   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9884   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);
9885   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9886   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9887   MatCheckPreallocated(A,1);
9888 
9889   ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&flg);CHKERRQ(ierr);
9890   if (flg) {
9891     ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr);
9892     ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr);
9893     PetscFunctionReturn(0);
9894   }
9895   if (scall == MAT_REUSE_MATRIX) {
9896     PetscValidPointer(*C,5);
9897     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9898     ierr = PetscObjectTypeCompareAny((PetscObject)*C,&flg,MATDENSE,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9899     if (flg) {
9900       ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9901       ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9902       ierr = (*(*C)->ops->transposematmultnumeric)(A,B,*C);CHKERRQ(ierr);
9903       ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9904       ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9905       PetscFunctionReturn(0);
9906     }
9907   }
9908 
9909   fA = A->ops->transposematmult;
9910   fB = B->ops->transposematmult;
9911   if (fB == fA && fA) transposematmult = fA;
9912   else {
9913     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9914     char multname[256];
9915     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
9916     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9917     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9918     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9919     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9920     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9921     if (!transposematmult) {
9922       ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr);
9923     }
9924     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);
9925   }
9926   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9927   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9928   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9929   PetscFunctionReturn(0);
9930 }
9931 
9932 /*@
9933    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9934 
9935    Neighbor-wise Collective on Mat
9936 
9937    Input Parameters:
9938 +  A - the left matrix
9939 .  B - the middle matrix
9940 .  C - the right matrix
9941 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9942 -  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
9943           if the result is a dense matrix this is irrelevent
9944 
9945    Output Parameters:
9946 .  D - the product matrix
9947 
9948    Notes:
9949    Unless scall is MAT_REUSE_MATRIX D will be created.
9950 
9951    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9952 
9953    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9954    actually needed.
9955 
9956    If you have many matrices with the same non-zero structure to multiply, you
9957    should use MAT_REUSE_MATRIX in all calls but the first or
9958 
9959    Level: intermediate
9960 
9961 .seealso: MatMatMult, MatPtAP()
9962 @*/
9963 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9964 {
9965   PetscErrorCode ierr;
9966   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9967   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9968   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9969   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9970 
9971   PetscFunctionBegin;
9972   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9973   PetscValidType(A,1);
9974   MatCheckPreallocated(A,1);
9975   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9976   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9977   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9978   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9979   PetscValidType(B,2);
9980   MatCheckPreallocated(B,2);
9981   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9982   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9983   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9984   PetscValidPointer(C,3);
9985   MatCheckPreallocated(C,3);
9986   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9987   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9988   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);
9989   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);
9990   if (scall == MAT_REUSE_MATRIX) {
9991     PetscValidPointer(*D,6);
9992     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9993     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9994     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9995     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9996     PetscFunctionReturn(0);
9997   }
9998   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9999   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10000 
10001   fA = A->ops->matmatmult;
10002   fB = B->ops->matmatmult;
10003   fC = C->ops->matmatmult;
10004   if (fA == fB && fA == fC) {
10005     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10006     mult = fA;
10007   } else {
10008     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10009     char multname[256];
10010     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10011     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10012     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10013     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10014     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10015     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10016     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10017     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10018     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);
10019   }
10020   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10021   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10022   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10023   PetscFunctionReturn(0);
10024 }
10025 
10026 /*@
10027    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10028 
10029    Collective on Mat
10030 
10031    Input Parameters:
10032 +  mat - the matrix
10033 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10034 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10035 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10036 
10037    Output Parameter:
10038 .  matredundant - redundant matrix
10039 
10040    Notes:
10041    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10042    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10043 
10044    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10045    calling it.
10046 
10047    Level: advanced
10048 
10049 
10050 .seealso: MatDestroy()
10051 @*/
10052 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10053 {
10054   PetscErrorCode ierr;
10055   MPI_Comm       comm;
10056   PetscMPIInt    size;
10057   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10058   Mat_Redundant  *redund=NULL;
10059   PetscSubcomm   psubcomm=NULL;
10060   MPI_Comm       subcomm_in=subcomm;
10061   Mat            *matseq;
10062   IS             isrow,iscol;
10063   PetscBool      newsubcomm=PETSC_FALSE;
10064 
10065   PetscFunctionBegin;
10066   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10067   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10068     PetscValidPointer(*matredundant,5);
10069     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10070   }
10071 
10072   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10073   if (size == 1 || nsubcomm == 1) {
10074     if (reuse == MAT_INITIAL_MATRIX) {
10075       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10076     } else {
10077       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");
10078       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10079     }
10080     PetscFunctionReturn(0);
10081   }
10082 
10083   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10084   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10085   MatCheckPreallocated(mat,1);
10086 
10087   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10088   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10089     /* create psubcomm, then get subcomm */
10090     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10091     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10092     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10093 
10094     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10095     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10096     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10097     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10098     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10099     newsubcomm = PETSC_TRUE;
10100     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10101   }
10102 
10103   /* get isrow, iscol and a local sequential matrix matseq[0] */
10104   if (reuse == MAT_INITIAL_MATRIX) {
10105     mloc_sub = PETSC_DECIDE;
10106     nloc_sub = PETSC_DECIDE;
10107     if (bs < 1) {
10108       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10109       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10110     } else {
10111       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10112       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10113     }
10114     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10115     rstart = rend - mloc_sub;
10116     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10117     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10118   } else { /* reuse == MAT_REUSE_MATRIX */
10119     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");
10120     /* retrieve subcomm */
10121     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10122     redund = (*matredundant)->redundant;
10123     isrow  = redund->isrow;
10124     iscol  = redund->iscol;
10125     matseq = redund->matseq;
10126   }
10127   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10128 
10129   /* get matredundant over subcomm */
10130   if (reuse == MAT_INITIAL_MATRIX) {
10131     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10132 
10133     /* create a supporting struct and attach it to C for reuse */
10134     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10135     (*matredundant)->redundant = redund;
10136     redund->isrow              = isrow;
10137     redund->iscol              = iscol;
10138     redund->matseq             = matseq;
10139     if (newsubcomm) {
10140       redund->subcomm          = subcomm;
10141     } else {
10142       redund->subcomm          = MPI_COMM_NULL;
10143     }
10144   } else {
10145     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10146   }
10147   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10148   PetscFunctionReturn(0);
10149 }
10150 
10151 /*@C
10152    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10153    a given 'mat' object. Each submatrix can span multiple procs.
10154 
10155    Collective on Mat
10156 
10157    Input Parameters:
10158 +  mat - the matrix
10159 .  subcomm - the subcommunicator obtained by com_split(comm)
10160 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10161 
10162    Output Parameter:
10163 .  subMat - 'parallel submatrices each spans a given subcomm
10164 
10165   Notes:
10166   The submatrix partition across processors is dictated by 'subComm' a
10167   communicator obtained by com_split(comm). The comm_split
10168   is not restriced to be grouped with consecutive original ranks.
10169 
10170   Due the comm_split() usage, the parallel layout of the submatrices
10171   map directly to the layout of the original matrix [wrt the local
10172   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10173   into the 'DiagonalMat' of the subMat, hence it is used directly from
10174   the subMat. However the offDiagMat looses some columns - and this is
10175   reconstructed with MatSetValues()
10176 
10177   Level: advanced
10178 
10179 
10180 .seealso: MatCreateSubMatrices()
10181 @*/
10182 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10183 {
10184   PetscErrorCode ierr;
10185   PetscMPIInt    commsize,subCommSize;
10186 
10187   PetscFunctionBegin;
10188   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10189   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10190   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10191 
10192   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");
10193   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10194   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10195   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10196   PetscFunctionReturn(0);
10197 }
10198 
10199 /*@
10200    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10201 
10202    Not Collective
10203 
10204    Input Arguments:
10205 +  mat - matrix to extract local submatrix from
10206 .  isrow - local row indices for submatrix
10207 -  iscol - local column indices for submatrix
10208 
10209    Output Arguments:
10210 .  submat - the submatrix
10211 
10212    Level: intermediate
10213 
10214    Notes:
10215    The submat should be returned with MatRestoreLocalSubMatrix().
10216 
10217    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10218    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10219 
10220    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10221    MatSetValuesBlockedLocal() will also be implemented.
10222 
10223    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10224    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10225 
10226 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10227 @*/
10228 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10229 {
10230   PetscErrorCode ierr;
10231 
10232   PetscFunctionBegin;
10233   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10234   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10235   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10236   PetscCheckSameComm(isrow,2,iscol,3);
10237   PetscValidPointer(submat,4);
10238   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10239 
10240   if (mat->ops->getlocalsubmatrix) {
10241     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10242   } else {
10243     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10244   }
10245   PetscFunctionReturn(0);
10246 }
10247 
10248 /*@
10249    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10250 
10251    Not Collective
10252 
10253    Input Arguments:
10254    mat - matrix to extract local submatrix from
10255    isrow - local row indices for submatrix
10256    iscol - local column indices for submatrix
10257    submat - the submatrix
10258 
10259    Level: intermediate
10260 
10261 .seealso: MatGetLocalSubMatrix()
10262 @*/
10263 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10264 {
10265   PetscErrorCode ierr;
10266 
10267   PetscFunctionBegin;
10268   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10269   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10270   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10271   PetscCheckSameComm(isrow,2,iscol,3);
10272   PetscValidPointer(submat,4);
10273   if (*submat) {
10274     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10275   }
10276 
10277   if (mat->ops->restorelocalsubmatrix) {
10278     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10279   } else {
10280     ierr = MatDestroy(submat);CHKERRQ(ierr);
10281   }
10282   *submat = NULL;
10283   PetscFunctionReturn(0);
10284 }
10285 
10286 /* --------------------------------------------------------*/
10287 /*@
10288    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10289 
10290    Collective on Mat
10291 
10292    Input Parameter:
10293 .  mat - the matrix
10294 
10295    Output Parameter:
10296 .  is - if any rows have zero diagonals this contains the list of them
10297 
10298    Level: developer
10299 
10300 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10301 @*/
10302 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10303 {
10304   PetscErrorCode ierr;
10305 
10306   PetscFunctionBegin;
10307   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10308   PetscValidType(mat,1);
10309   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10310   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10311 
10312   if (!mat->ops->findzerodiagonals) {
10313     Vec                diag;
10314     const PetscScalar *a;
10315     PetscInt          *rows;
10316     PetscInt           rStart, rEnd, r, nrow = 0;
10317 
10318     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10319     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10320     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10321     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10322     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10323     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10324     nrow = 0;
10325     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10326     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10327     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10328     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10329   } else {
10330     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10331   }
10332   PetscFunctionReturn(0);
10333 }
10334 
10335 /*@
10336    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10337 
10338    Collective on Mat
10339 
10340    Input Parameter:
10341 .  mat - the matrix
10342 
10343    Output Parameter:
10344 .  is - contains the list of rows with off block diagonal entries
10345 
10346    Level: developer
10347 
10348 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10349 @*/
10350 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10351 {
10352   PetscErrorCode ierr;
10353 
10354   PetscFunctionBegin;
10355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10356   PetscValidType(mat,1);
10357   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10358   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10359 
10360   if (!mat->ops->findoffblockdiagonalentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name);
10361   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10362   PetscFunctionReturn(0);
10363 }
10364 
10365 /*@C
10366   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10367 
10368   Collective on Mat
10369 
10370   Input Parameters:
10371 . mat - the matrix
10372 
10373   Output Parameters:
10374 . values - the block inverses in column major order (FORTRAN-like)
10375 
10376    Note:
10377    This routine is not available from Fortran.
10378 
10379   Level: advanced
10380 
10381 .seealso: MatInvertBockDiagonalMat
10382 @*/
10383 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10384 {
10385   PetscErrorCode ierr;
10386 
10387   PetscFunctionBegin;
10388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10389   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10390   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10391   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10392   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10393   PetscFunctionReturn(0);
10394 }
10395 
10396 /*@C
10397   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10398 
10399   Collective on Mat
10400 
10401   Input Parameters:
10402 + mat - the matrix
10403 . nblocks - the number of blocks
10404 - bsizes - the size of each block
10405 
10406   Output Parameters:
10407 . values - the block inverses in column major order (FORTRAN-like)
10408 
10409    Note:
10410    This routine is not available from Fortran.
10411 
10412   Level: advanced
10413 
10414 .seealso: MatInvertBockDiagonal()
10415 @*/
10416 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10417 {
10418   PetscErrorCode ierr;
10419 
10420   PetscFunctionBegin;
10421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10422   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10423   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10424   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
10425   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10426   PetscFunctionReturn(0);
10427 }
10428 
10429 /*@
10430   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10431 
10432   Collective on Mat
10433 
10434   Input Parameters:
10435 . A - the matrix
10436 
10437   Output Parameters:
10438 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10439 
10440   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10441 
10442   Level: advanced
10443 
10444 .seealso: MatInvertBockDiagonal()
10445 @*/
10446 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10447 {
10448   PetscErrorCode     ierr;
10449   const PetscScalar *vals;
10450   PetscInt          *dnnz;
10451   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10452 
10453   PetscFunctionBegin;
10454   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10455   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10456   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10457   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10458   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10459   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10460   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10461   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10462   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10463   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10464   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10465   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10466   for (i = rstart/bs; i < rend/bs; i++) {
10467     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10468   }
10469   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10470   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10471   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10472   PetscFunctionReturn(0);
10473 }
10474 
10475 /*@C
10476     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10477     via MatTransposeColoringCreate().
10478 
10479     Collective on MatTransposeColoring
10480 
10481     Input Parameter:
10482 .   c - coloring context
10483 
10484     Level: intermediate
10485 
10486 .seealso: MatTransposeColoringCreate()
10487 @*/
10488 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10489 {
10490   PetscErrorCode       ierr;
10491   MatTransposeColoring matcolor=*c;
10492 
10493   PetscFunctionBegin;
10494   if (!matcolor) PetscFunctionReturn(0);
10495   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10496 
10497   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10498   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10499   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10500   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10501   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10502   if (matcolor->brows>0) {
10503     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10504   }
10505   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10506   PetscFunctionReturn(0);
10507 }
10508 
10509 /*@C
10510     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10511     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10512     MatTransposeColoring to sparse B.
10513 
10514     Collective on MatTransposeColoring
10515 
10516     Input Parameters:
10517 +   B - sparse matrix B
10518 .   Btdense - symbolic dense matrix B^T
10519 -   coloring - coloring context created with MatTransposeColoringCreate()
10520 
10521     Output Parameter:
10522 .   Btdense - dense matrix B^T
10523 
10524     Level: advanced
10525 
10526      Notes:
10527     These are used internally for some implementations of MatRARt()
10528 
10529 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10530 
10531 @*/
10532 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10533 {
10534   PetscErrorCode ierr;
10535 
10536   PetscFunctionBegin;
10537   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10538   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10539   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10540 
10541   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10542   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10543   PetscFunctionReturn(0);
10544 }
10545 
10546 /*@C
10547     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10548     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10549     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10550     Csp from Cden.
10551 
10552     Collective on MatTransposeColoring
10553 
10554     Input Parameters:
10555 +   coloring - coloring context created with MatTransposeColoringCreate()
10556 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10557 
10558     Output Parameter:
10559 .   Csp - sparse matrix
10560 
10561     Level: advanced
10562 
10563      Notes:
10564     These are used internally for some implementations of MatRARt()
10565 
10566 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10567 
10568 @*/
10569 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10570 {
10571   PetscErrorCode ierr;
10572 
10573   PetscFunctionBegin;
10574   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10575   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10576   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10577 
10578   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10579   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10580   PetscFunctionReturn(0);
10581 }
10582 
10583 /*@C
10584    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10585 
10586    Collective on Mat
10587 
10588    Input Parameters:
10589 +  mat - the matrix product C
10590 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10591 
10592     Output Parameter:
10593 .   color - the new coloring context
10594 
10595     Level: intermediate
10596 
10597 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10598            MatTransColoringApplyDenToSp()
10599 @*/
10600 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10601 {
10602   MatTransposeColoring c;
10603   MPI_Comm             comm;
10604   PetscErrorCode       ierr;
10605 
10606   PetscFunctionBegin;
10607   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10608   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10609   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10610 
10611   c->ctype = iscoloring->ctype;
10612   if (mat->ops->transposecoloringcreate) {
10613     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10614   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10615 
10616   *color = c;
10617   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10618   PetscFunctionReturn(0);
10619 }
10620 
10621 /*@
10622       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10623         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10624         same, otherwise it will be larger
10625 
10626      Not Collective
10627 
10628   Input Parameter:
10629 .    A  - the matrix
10630 
10631   Output Parameter:
10632 .    state - the current state
10633 
10634   Notes:
10635     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10636          different matrices
10637 
10638   Level: intermediate
10639 
10640 @*/
10641 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10642 {
10643   PetscFunctionBegin;
10644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10645   *state = mat->nonzerostate;
10646   PetscFunctionReturn(0);
10647 }
10648 
10649 /*@
10650       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10651                  matrices from each processor
10652 
10653     Collective
10654 
10655    Input Parameters:
10656 +    comm - the communicators the parallel matrix will live on
10657 .    seqmat - the input sequential matrices
10658 .    n - number of local columns (or PETSC_DECIDE)
10659 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10660 
10661    Output Parameter:
10662 .    mpimat - the parallel matrix generated
10663 
10664     Level: advanced
10665 
10666    Notes:
10667     The number of columns of the matrix in EACH processor MUST be the same.
10668 
10669 @*/
10670 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10671 {
10672   PetscErrorCode ierr;
10673 
10674   PetscFunctionBegin;
10675   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10676   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");
10677 
10678   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10679   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10680   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10681   PetscFunctionReturn(0);
10682 }
10683 
10684 /*@
10685      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10686                  ranks' ownership ranges.
10687 
10688     Collective on A
10689 
10690    Input Parameters:
10691 +    A   - the matrix to create subdomains from
10692 -    N   - requested number of subdomains
10693 
10694 
10695    Output Parameters:
10696 +    n   - number of subdomains resulting on this rank
10697 -    iss - IS list with indices of subdomains on this rank
10698 
10699     Level: advanced
10700 
10701     Notes:
10702     number of subdomains must be smaller than the communicator size
10703 @*/
10704 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10705 {
10706   MPI_Comm        comm,subcomm;
10707   PetscMPIInt     size,rank,color;
10708   PetscInt        rstart,rend,k;
10709   PetscErrorCode  ierr;
10710 
10711   PetscFunctionBegin;
10712   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10713   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10714   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10715   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);
10716   *n = 1;
10717   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10718   color = rank/k;
10719   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10720   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10721   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10722   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10723   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10724   PetscFunctionReturn(0);
10725 }
10726 
10727 /*@
10728    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10729 
10730    If the interpolation and restriction operators are the same, uses MatPtAP.
10731    If they are not the same, use MatMatMatMult.
10732 
10733    Once the coarse grid problem is constructed, correct for interpolation operators
10734    that are not of full rank, which can legitimately happen in the case of non-nested
10735    geometric multigrid.
10736 
10737    Input Parameters:
10738 +  restrct - restriction operator
10739 .  dA - fine grid matrix
10740 .  interpolate - interpolation operator
10741 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10742 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10743 
10744    Output Parameters:
10745 .  A - the Galerkin coarse matrix
10746 
10747    Options Database Key:
10748 .  -pc_mg_galerkin <both,pmat,mat,none>
10749 
10750    Level: developer
10751 
10752 .seealso: MatPtAP(), MatMatMatMult()
10753 @*/
10754 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10755 {
10756   PetscErrorCode ierr;
10757   IS             zerorows;
10758   Vec            diag;
10759 
10760   PetscFunctionBegin;
10761   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10762   /* Construct the coarse grid matrix */
10763   if (interpolate == restrct) {
10764     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10765   } else {
10766     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10767   }
10768 
10769   /* If the interpolation matrix is not of full rank, A will have zero rows.
10770      This can legitimately happen in the case of non-nested geometric multigrid.
10771      In that event, we set the rows of the matrix to the rows of the identity,
10772      ignoring the equations (as the RHS will also be zero). */
10773 
10774   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10775 
10776   if (zerorows != NULL) { /* if there are any zero rows */
10777     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10778     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10779     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10780     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10781     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10782     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10783   }
10784   PetscFunctionReturn(0);
10785 }
10786 
10787 /*@C
10788     MatSetOperation - Allows user to set a matrix operation for any matrix type
10789 
10790    Logically Collective on Mat
10791 
10792     Input Parameters:
10793 +   mat - the matrix
10794 .   op - the name of the operation
10795 -   f - the function that provides the operation
10796 
10797    Level: developer
10798 
10799     Usage:
10800 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10801 $      ierr = MatCreateXXX(comm,...&A);
10802 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10803 
10804     Notes:
10805     See the file include/petscmat.h for a complete list of matrix
10806     operations, which all have the form MATOP_<OPERATION>, where
10807     <OPERATION> is the name (in all capital letters) of the
10808     user interface routine (e.g., MatMult() -> MATOP_MULT).
10809 
10810     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10811     sequence as the usual matrix interface routines, since they
10812     are intended to be accessed via the usual matrix interface
10813     routines, e.g.,
10814 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10815 
10816     In particular each function MUST return an error code of 0 on success and
10817     nonzero on failure.
10818 
10819     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10820 
10821 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10822 @*/
10823 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10824 {
10825   PetscFunctionBegin;
10826   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10827   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10828     mat->ops->viewnative = mat->ops->view;
10829   }
10830   (((void(**)(void))mat->ops)[op]) = f;
10831   PetscFunctionReturn(0);
10832 }
10833 
10834 /*@C
10835     MatGetOperation - Gets a matrix operation for any matrix type.
10836 
10837     Not Collective
10838 
10839     Input Parameters:
10840 +   mat - the matrix
10841 -   op - the name of the operation
10842 
10843     Output Parameter:
10844 .   f - the function that provides the operation
10845 
10846     Level: developer
10847 
10848     Usage:
10849 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10850 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10851 
10852     Notes:
10853     See the file include/petscmat.h for a complete list of matrix
10854     operations, which all have the form MATOP_<OPERATION>, where
10855     <OPERATION> is the name (in all capital letters) of the
10856     user interface routine (e.g., MatMult() -> MATOP_MULT).
10857 
10858     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10859 
10860 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10861 @*/
10862 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10863 {
10864   PetscFunctionBegin;
10865   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10866   *f = (((void (**)(void))mat->ops)[op]);
10867   PetscFunctionReturn(0);
10868 }
10869 
10870 /*@
10871     MatHasOperation - Determines whether the given matrix supports the particular
10872     operation.
10873 
10874    Not Collective
10875 
10876    Input Parameters:
10877 +  mat - the matrix
10878 -  op - the operation, for example, MATOP_GET_DIAGONAL
10879 
10880    Output Parameter:
10881 .  has - either PETSC_TRUE or PETSC_FALSE
10882 
10883    Level: advanced
10884 
10885    Notes:
10886    See the file include/petscmat.h for a complete list of matrix
10887    operations, which all have the form MATOP_<OPERATION>, where
10888    <OPERATION> is the name (in all capital letters) of the
10889    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10890 
10891 .seealso: MatCreateShell()
10892 @*/
10893 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10894 {
10895   PetscErrorCode ierr;
10896 
10897   PetscFunctionBegin;
10898   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10899   PetscValidType(mat,1);
10900   PetscValidPointer(has,3);
10901   if (mat->ops->hasoperation) {
10902     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10903   } else {
10904     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10905     else {
10906       *has = PETSC_FALSE;
10907       if (op == MATOP_CREATE_SUBMATRIX) {
10908         PetscMPIInt size;
10909 
10910         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10911         if (size == 1) {
10912           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10913         }
10914       }
10915     }
10916   }
10917   PetscFunctionReturn(0);
10918 }
10919 
10920 /*@
10921     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10922     of the matrix are congruent
10923 
10924    Collective on mat
10925 
10926    Input Parameters:
10927 .  mat - the matrix
10928 
10929    Output Parameter:
10930 .  cong - either PETSC_TRUE or PETSC_FALSE
10931 
10932    Level: beginner
10933 
10934    Notes:
10935 
10936 .seealso: MatCreate(), MatSetSizes()
10937 @*/
10938 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10939 {
10940   PetscErrorCode ierr;
10941 
10942   PetscFunctionBegin;
10943   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10944   PetscValidType(mat,1);
10945   PetscValidPointer(cong,2);
10946   if (!mat->rmap || !mat->cmap) {
10947     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10948     PetscFunctionReturn(0);
10949   }
10950   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10951     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10952     if (*cong) mat->congruentlayouts = 1;
10953     else       mat->congruentlayouts = 0;
10954   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10955   PetscFunctionReturn(0);
10956 }
10957 
10958 /*@
10959     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
10960     e.g., matrx product of MatPtAP.
10961 
10962    Collective on mat
10963 
10964    Input Parameters:
10965 .  mat - the matrix
10966 
10967    Output Parameter:
10968 .  mat - the matrix with intermediate data structures released
10969 
10970    Level: advanced
10971 
10972    Notes:
10973 
10974 .seealso: MatPtAP(), MatMatMult()
10975 @*/
10976 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
10977 {
10978   PetscErrorCode ierr;
10979 
10980   PetscFunctionBegin;
10981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10982   PetscValidType(mat,1);
10983   if (mat->ops->freeintermediatedatastructures) {
10984     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
10985   }
10986   PetscFunctionReturn(0);
10987 }
10988