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