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