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