xref: /petsc/src/mat/interface/matrix.c (revision b465f1d72a3b3367c0707c02b5b679af4d2b07f0)
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, Windows and the 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 restart and less than rend where restart and rend are obtainable
1918      from MatGetOwnershipRange(mat,&rstart,&rend).
1919 
1920    Level: advanced
1921 
1922 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues(), MatGetOwnershipRange(), MatGetValuesLocal()
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 restart and less than rend where restart 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 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4246 {
4247   PetscErrorCode ierr;
4248   PetscInt       i;
4249 
4250   PetscFunctionBegin;
4251   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4252   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4253   PetscValidType(A,1);
4254   PetscValidType(B,2);
4255   PetscCheckSameComm(A,1,B,2);
4256   MatCheckPreallocated(B,2);
4257   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4258   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4259   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);
4260   MatCheckPreallocated(A,1);
4261   if (A == B) PetscFunctionReturn(0);
4262 
4263   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4264   if (A->ops->copy) {
4265     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4266   } else { /* generic conversion */
4267     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4268   }
4269 
4270   B->stencil.dim = A->stencil.dim;
4271   B->stencil.noc = A->stencil.noc;
4272   for (i=0; i<=A->stencil.dim; i++) {
4273     B->stencil.dims[i]   = A->stencil.dims[i];
4274     B->stencil.starts[i] = A->stencil.starts[i];
4275   }
4276 
4277   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4278   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4279   PetscFunctionReturn(0);
4280 }
4281 
4282 /*@C
4283    MatConvert - Converts a matrix to another matrix, either of the same
4284    or different type.
4285 
4286    Collective on Mat
4287 
4288    Input Parameters:
4289 +  mat - the matrix
4290 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4291    same type as the original matrix.
4292 -  reuse - denotes if the destination matrix is to be created or reused.
4293    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
4294    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).
4295 
4296    Output Parameter:
4297 .  M - pointer to place new matrix
4298 
4299    Notes:
4300    MatConvert() first creates a new matrix and then copies the data from
4301    the first matrix.  A related routine is MatCopy(), which copies the matrix
4302    entries of one matrix to another already existing matrix context.
4303 
4304    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4305    the MPI communicator of the generated matrix is always the same as the communicator
4306    of the input matrix.
4307 
4308    Level: intermediate
4309 
4310 .seealso: MatCopy(), MatDuplicate()
4311 @*/
4312 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4313 {
4314   PetscErrorCode ierr;
4315   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4316   char           convname[256],mtype[256];
4317   Mat            B;
4318 
4319   PetscFunctionBegin;
4320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4321   PetscValidType(mat,1);
4322   PetscValidPointer(M,4);
4323   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4324   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4325   MatCheckPreallocated(mat,1);
4326 
4327   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg);CHKERRQ(ierr);
4328   if (flg) newtype = mtype;
4329 
4330   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4331   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4332   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4333   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");
4334 
4335   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4336     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4337     PetscFunctionReturn(0);
4338   }
4339 
4340   /* Cache Mat options because some converter use MatHeaderReplace  */
4341   issymmetric = mat->symmetric;
4342   ishermitian = mat->hermitian;
4343 
4344   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4345     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4346     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4347   } else {
4348     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4349     const char     *prefix[3] = {"seq","mpi",""};
4350     PetscInt       i;
4351     /*
4352        Order of precedence:
4353        0) See if newtype is a superclass of the current matrix.
4354        1) See if a specialized converter is known to the current matrix.
4355        2) See if a specialized converter is known to the desired matrix class.
4356        3) See if a good general converter is registered for the desired class
4357           (as of 6/27/03 only MATMPIADJ falls into this category).
4358        4) See if a good general converter is known for the current matrix.
4359        5) Use a really basic converter.
4360     */
4361 
4362     /* 0) See if newtype is a superclass of the current matrix.
4363           i.e mat is mpiaij and newtype is aij */
4364     for (i=0; i<2; i++) {
4365       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4366       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4367       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4368       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4369       if (flg) {
4370         if (reuse == MAT_INPLACE_MATRIX) {
4371           ierr = PetscInfo(mat,"Early return\n");CHKERRQ(ierr);
4372           PetscFunctionReturn(0);
4373         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4374           ierr = PetscInfo(mat,"Calling MatDuplicate\n");CHKERRQ(ierr);
4375           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4376           PetscFunctionReturn(0);
4377         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4378           ierr = PetscInfo(mat,"Calling MatCopy\n");CHKERRQ(ierr);
4379           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4380           PetscFunctionReturn(0);
4381         }
4382       }
4383     }
4384     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4385     for (i=0; i<3; i++) {
4386       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4387       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4388       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4389       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4390       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4391       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4392       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4393       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4394       if (conv) goto foundconv;
4395     }
4396 
4397     /* 2)  See if a specialized converter is known to the desired matrix class. */
4398     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4399     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4400     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4401     for (i=0; i<3; i++) {
4402       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4403       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4404       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4405       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4406       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4407       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4408       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4409       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4410       if (conv) {
4411         ierr = MatDestroy(&B);CHKERRQ(ierr);
4412         goto foundconv;
4413       }
4414     }
4415 
4416     /* 3) See if a good general converter is registered for the desired class */
4417     conv = B->ops->convertfrom;
4418     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4419     ierr = MatDestroy(&B);CHKERRQ(ierr);
4420     if (conv) goto foundconv;
4421 
4422     /* 4) See if a good general converter is known for the current matrix */
4423     if (mat->ops->convert) conv = mat->ops->convert;
4424 
4425     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4426     if (conv) goto foundconv;
4427 
4428     /* 5) Use a really basic converter. */
4429     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4430     conv = MatConvert_Basic;
4431 
4432 foundconv:
4433     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4434     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4435     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4436       /* the block sizes must be same if the mappings are copied over */
4437       (*M)->rmap->bs = mat->rmap->bs;
4438       (*M)->cmap->bs = mat->cmap->bs;
4439       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4440       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4441       (*M)->rmap->mapping = mat->rmap->mapping;
4442       (*M)->cmap->mapping = mat->cmap->mapping;
4443     }
4444     (*M)->stencil.dim = mat->stencil.dim;
4445     (*M)->stencil.noc = mat->stencil.noc;
4446     for (i=0; i<=mat->stencil.dim; i++) {
4447       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4448       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4449     }
4450     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4451   }
4452   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4453 
4454   /* Copy Mat options */
4455   if (issymmetric) {
4456     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4457   }
4458   if (ishermitian) {
4459     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4460   }
4461   PetscFunctionReturn(0);
4462 }
4463 
4464 /*@C
4465    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4466 
4467    Not Collective
4468 
4469    Input Parameter:
4470 .  mat - the matrix, must be a factored matrix
4471 
4472    Output Parameter:
4473 .   type - the string name of the package (do not free this string)
4474 
4475    Notes:
4476       In Fortran you pass in a empty string and the package name will be copied into it.
4477     (Make sure the string is long enough)
4478 
4479    Level: intermediate
4480 
4481 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4482 @*/
4483 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4484 {
4485   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4486 
4487   PetscFunctionBegin;
4488   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4489   PetscValidType(mat,1);
4490   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4491   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4492   if (!conv) {
4493     *type = MATSOLVERPETSC;
4494   } else {
4495     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4496   }
4497   PetscFunctionReturn(0);
4498 }
4499 
4500 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4501 struct _MatSolverTypeForSpecifcType {
4502   MatType                        mtype;
4503   /* no entry for MAT_FACTOR_NONE */
4504   PetscErrorCode                 (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*);
4505   MatSolverTypeForSpecifcType next;
4506 };
4507 
4508 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4509 struct _MatSolverTypeHolder {
4510   char                        *name;
4511   MatSolverTypeForSpecifcType handlers;
4512   MatSolverTypeHolder         next;
4513 };
4514 
4515 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4516 
4517 /*@C
4518    MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type
4519 
4520    Input Parameters:
4521 +    package - name of the package, for example petsc or superlu
4522 .    mtype - the matrix type that works with this package
4523 .    ftype - the type of factorization supported by the package
4524 -    createfactor - routine that will create the factored matrix ready to be used
4525 
4526     Level: intermediate
4527 
4528 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4529 @*/
4530 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*))
4531 {
4532   PetscErrorCode              ierr;
4533   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4534   PetscBool                   flg;
4535   MatSolverTypeForSpecifcType inext,iprev = NULL;
4536 
4537   PetscFunctionBegin;
4538   ierr = MatInitializePackage();CHKERRQ(ierr);
4539   if (!next) {
4540     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4541     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4542     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4543     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4544     MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor;
4545     PetscFunctionReturn(0);
4546   }
4547   while (next) {
4548     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4549     if (flg) {
4550       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4551       inext = next->handlers;
4552       while (inext) {
4553         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4554         if (flg) {
4555           inext->createfactor[(int)ftype-1] = createfactor;
4556           PetscFunctionReturn(0);
4557         }
4558         iprev = inext;
4559         inext = inext->next;
4560       }
4561       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4562       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4563       iprev->next->createfactor[(int)ftype-1] = createfactor;
4564       PetscFunctionReturn(0);
4565     }
4566     prev = next;
4567     next = next->next;
4568   }
4569   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4570   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4571   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4572   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4573   prev->next->handlers->createfactor[(int)ftype-1] = createfactor;
4574   PetscFunctionReturn(0);
4575 }
4576 
4577 /*@C
4578    MatSolveTypeGet - Gets the function that creates the factor matrix if it exist
4579 
4580    Input Parameters:
4581 +    type - name of the package, for example petsc or superlu
4582 .    ftype - the type of factorization supported by the type
4583 -    mtype - the matrix type that works with this type
4584 
4585    Output Parameters:
4586 +   foundtype - PETSC_TRUE if the type was registered
4587 .   foundmtype - PETSC_TRUE if the type supports the requested mtype
4588 -   createfactor - routine that will create the factored matrix ready to be used or NULL if not found
4589 
4590     Level: intermediate
4591 
4592 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolverTypeRegister(), MatGetFactor()
4593 @*/
4594 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*))
4595 {
4596   PetscErrorCode              ierr;
4597   MatSolverTypeHolder         next = MatSolverTypeHolders;
4598   PetscBool                   flg;
4599   MatSolverTypeForSpecifcType inext;
4600 
4601   PetscFunctionBegin;
4602   if (foundtype) *foundtype = PETSC_FALSE;
4603   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4604   if (createfactor) *createfactor    = NULL;
4605 
4606   if (type) {
4607     while (next) {
4608       ierr = PetscStrcasecmp(type,next->name,&flg);CHKERRQ(ierr);
4609       if (flg) {
4610         if (foundtype) *foundtype = PETSC_TRUE;
4611         inext = next->handlers;
4612         while (inext) {
4613           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4614           if (flg) {
4615             if (foundmtype) *foundmtype = PETSC_TRUE;
4616             if (createfactor)  *createfactor  = inext->createfactor[(int)ftype-1];
4617             PetscFunctionReturn(0);
4618           }
4619           inext = inext->next;
4620         }
4621       }
4622       next = next->next;
4623     }
4624   } else {
4625     while (next) {
4626       inext = next->handlers;
4627       while (inext) {
4628         ierr = PetscStrcmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4629         if (flg && inext->createfactor[(int)ftype-1]) {
4630           if (foundtype) *foundtype = PETSC_TRUE;
4631           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4632           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4633           PetscFunctionReturn(0);
4634         }
4635         inext = inext->next;
4636       }
4637       next = next->next;
4638     }
4639     /* try with base classes inext->mtype */
4640     next = MatSolverTypeHolders;
4641     while (next) {
4642       inext = next->handlers;
4643       while (inext) {
4644         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4645         if (flg && inext->createfactor[(int)ftype-1]) {
4646           if (foundtype) *foundtype = PETSC_TRUE;
4647           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4648           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4649           PetscFunctionReturn(0);
4650         }
4651         inext = inext->next;
4652       }
4653       next = next->next;
4654     }
4655   }
4656   PetscFunctionReturn(0);
4657 }
4658 
4659 PetscErrorCode MatSolverTypeDestroy(void)
4660 {
4661   PetscErrorCode              ierr;
4662   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4663   MatSolverTypeForSpecifcType inext,iprev;
4664 
4665   PetscFunctionBegin;
4666   while (next) {
4667     ierr = PetscFree(next->name);CHKERRQ(ierr);
4668     inext = next->handlers;
4669     while (inext) {
4670       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4671       iprev = inext;
4672       inext = inext->next;
4673       ierr = PetscFree(iprev);CHKERRQ(ierr);
4674     }
4675     prev = next;
4676     next = next->next;
4677     ierr = PetscFree(prev);CHKERRQ(ierr);
4678   }
4679   MatSolverTypeHolders = NULL;
4680   PetscFunctionReturn(0);
4681 }
4682 
4683 /*@C
4684    MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4685 
4686    Logically Collective on Mat
4687 
4688    Input Parameters:
4689 .  mat - the matrix
4690 
4691    Output Parameters:
4692 .  flg - PETSC_TRUE if uses the ordering
4693 
4694    Notes:
4695       Most internal PETSc factorizations use the ordering passed to the factorization routine but external
4696       packages do not, thus we want to skip generating the ordering when it is not needed or used.
4697 
4698    Level: developer
4699 
4700 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4701 @*/
4702 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg)
4703 {
4704   PetscFunctionBegin;
4705   *flg = mat->canuseordering;
4706   PetscFunctionReturn(0);
4707 }
4708 
4709 /*@C
4710    MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object
4711 
4712    Logically Collective on Mat
4713 
4714    Input Parameters:
4715 .  mat - the matrix
4716 
4717    Output Parameters:
4718 .  otype - the preferred type
4719 
4720    Level: developer
4721 
4722 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4723 @*/
4724 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype)
4725 {
4726   PetscFunctionBegin;
4727   *otype = mat->preferredordering[ftype];
4728   if (!*otype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering");
4729   PetscFunctionReturn(0);
4730 }
4731 
4732 /*@C
4733    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4734 
4735    Collective on Mat
4736 
4737    Input Parameters:
4738 +  mat - the matrix
4739 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4740 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4741 
4742    Output Parameters:
4743 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4744 
4745    Notes:
4746       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4747      such as pastix, superlu, mumps etc.
4748 
4749       PETSc must have been ./configure to use the external solver, using the option --download-package
4750 
4751    Developer Notes:
4752       This should actually be called MatCreateFactor() since it creates a new factor object
4753 
4754    Level: intermediate
4755 
4756 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetCanUseOrdering(), MatSolverTypeRegister()
4757 @*/
4758 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4759 {
4760   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4761   PetscBool      foundtype,foundmtype;
4762 
4763   PetscFunctionBegin;
4764   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4765   PetscValidType(mat,1);
4766 
4767   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4768   MatCheckPreallocated(mat,1);
4769 
4770   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr);
4771   if (!foundtype) {
4772     if (type) {
4773       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);
4774     } else {
4775       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);
4776     }
4777   }
4778   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4779   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);
4780 
4781   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4782   PetscFunctionReturn(0);
4783 }
4784 
4785 /*@C
4786    MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type
4787 
4788    Not Collective
4789 
4790    Input Parameters:
4791 +  mat - the matrix
4792 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4793 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4794 
4795    Output Parameter:
4796 .    flg - PETSC_TRUE if the factorization is available
4797 
4798    Notes:
4799       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4800      such as pastix, superlu, mumps etc.
4801 
4802       PETSc must have been ./configure to use the external solver, using the option --download-package
4803 
4804    Developer Notes:
4805       This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object
4806 
4807    Level: intermediate
4808 
4809 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister()
4810 @*/
4811 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4812 {
4813   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4814 
4815   PetscFunctionBegin;
4816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4817   PetscValidType(mat,1);
4818 
4819   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4820   MatCheckPreallocated(mat,1);
4821 
4822   *flg = PETSC_FALSE;
4823   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4824   if (gconv) {
4825     *flg = PETSC_TRUE;
4826   }
4827   PetscFunctionReturn(0);
4828 }
4829 
4830 /*@
4831    MatDuplicate - Duplicates a matrix including the non-zero structure.
4832 
4833    Collective on Mat
4834 
4835    Input Parameters:
4836 +  mat - the matrix
4837 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4838         See the manual page for MatDuplicateOption for an explanation of these options.
4839 
4840    Output Parameter:
4841 .  M - pointer to place new matrix
4842 
4843    Level: intermediate
4844 
4845    Notes:
4846     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4847     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.
4848 
4849 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4850 @*/
4851 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4852 {
4853   PetscErrorCode ierr;
4854   Mat            B;
4855   PetscInt       i;
4856   PetscObject    dm;
4857   void           (*viewf)(void);
4858 
4859   PetscFunctionBegin;
4860   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4861   PetscValidType(mat,1);
4862   PetscValidPointer(M,3);
4863   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4864   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4865   MatCheckPreallocated(mat,1);
4866 
4867   *M = NULL;
4868   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4869   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4870   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4871   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4872   B    = *M;
4873 
4874   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4875   if (viewf) {
4876     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4877   }
4878 
4879   B->stencil.dim = mat->stencil.dim;
4880   B->stencil.noc = mat->stencil.noc;
4881   for (i=0; i<=mat->stencil.dim; i++) {
4882     B->stencil.dims[i]   = mat->stencil.dims[i];
4883     B->stencil.starts[i] = mat->stencil.starts[i];
4884   }
4885 
4886   B->nooffproczerorows = mat->nooffproczerorows;
4887   B->nooffprocentries  = mat->nooffprocentries;
4888 
4889   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm);CHKERRQ(ierr);
4890   if (dm) {
4891     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm);CHKERRQ(ierr);
4892   }
4893   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4894   PetscFunctionReturn(0);
4895 }
4896 
4897 /*@
4898    MatGetDiagonal - Gets the diagonal of a matrix.
4899 
4900    Logically Collective on Mat
4901 
4902    Input Parameters:
4903 +  mat - the matrix
4904 -  v - the vector for storing the diagonal
4905 
4906    Output Parameter:
4907 .  v - the diagonal of the matrix
4908 
4909    Level: intermediate
4910 
4911    Note:
4912    Currently only correct in parallel for square matrices.
4913 
4914 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4915 @*/
4916 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4917 {
4918   PetscErrorCode ierr;
4919 
4920   PetscFunctionBegin;
4921   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4922   PetscValidType(mat,1);
4923   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4924   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4925   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4926   MatCheckPreallocated(mat,1);
4927 
4928   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4929   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4930   PetscFunctionReturn(0);
4931 }
4932 
4933 /*@C
4934    MatGetRowMin - Gets the minimum value (of the real part) of each
4935         row of the matrix
4936 
4937    Logically Collective on Mat
4938 
4939    Input Parameter:
4940 .  mat - the matrix
4941 
4942    Output Parameters:
4943 +  v - the vector for storing the maximums
4944 -  idx - the indices of the column found for each row (optional)
4945 
4946    Level: intermediate
4947 
4948    Notes:
4949     The result of this call are the same as if one converted the matrix to dense format
4950       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4951 
4952     This code is only implemented for a couple of matrix formats.
4953 
4954 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4955           MatGetRowMax()
4956 @*/
4957 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4958 {
4959   PetscErrorCode ierr;
4960 
4961   PetscFunctionBegin;
4962   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4963   PetscValidType(mat,1);
4964   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4965   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4966 
4967   if (!mat->cmap->N) {
4968     ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr);
4969     if (idx) {
4970       PetscInt i,m = mat->rmap->n;
4971       for (i=0; i<m; i++) idx[i] = -1;
4972     }
4973   } else {
4974     if (!mat->ops->getrowmin) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4975     MatCheckPreallocated(mat,1);
4976   }
4977   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4978   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4979   PetscFunctionReturn(0);
4980 }
4981 
4982 /*@C
4983    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4984         row of the matrix
4985 
4986    Logically Collective on Mat
4987 
4988    Input Parameter:
4989 .  mat - the matrix
4990 
4991    Output Parameters:
4992 +  v - the vector for storing the minimums
4993 -  idx - the indices of the column found for each row (or NULL if not needed)
4994 
4995    Level: intermediate
4996 
4997    Notes:
4998     if a row is completely empty or has only 0.0 values then the idx[] value for that
4999     row is 0 (the first column).
5000 
5001     This code is only implemented for a couple of matrix formats.
5002 
5003 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
5004 @*/
5005 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
5006 {
5007   PetscErrorCode ierr;
5008 
5009   PetscFunctionBegin;
5010   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5011   PetscValidType(mat,1);
5012   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5013   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5014   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5015 
5016   if (!mat->cmap->N) {
5017     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5018     if (idx) {
5019       PetscInt i,m = mat->rmap->n;
5020       for (i=0; i<m; i++) idx[i] = -1;
5021     }
5022   } else {
5023     if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5024     MatCheckPreallocated(mat,1);
5025     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5026     ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
5027   }
5028   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5029   PetscFunctionReturn(0);
5030 }
5031 
5032 /*@C
5033    MatGetRowMax - Gets the maximum value (of the real part) of each
5034         row of the matrix
5035 
5036    Logically Collective on Mat
5037 
5038    Input Parameter:
5039 .  mat - the matrix
5040 
5041    Output Parameters:
5042 +  v - the vector for storing the maximums
5043 -  idx - the indices of the column found for each row (optional)
5044 
5045    Level: intermediate
5046 
5047    Notes:
5048     The result of this call are the same as if one converted the matrix to dense format
5049       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
5050 
5051     This code is only implemented for a couple of matrix formats.
5052 
5053 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
5054 @*/
5055 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
5056 {
5057   PetscErrorCode ierr;
5058 
5059   PetscFunctionBegin;
5060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5061   PetscValidType(mat,1);
5062   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5063   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5064 
5065   if (!mat->cmap->N) {
5066     ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr);
5067     if (idx) {
5068       PetscInt i,m = mat->rmap->n;
5069       for (i=0; i<m; i++) idx[i] = -1;
5070     }
5071   } else {
5072     if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5073     MatCheckPreallocated(mat,1);
5074     ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
5075   }
5076   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5077   PetscFunctionReturn(0);
5078 }
5079 
5080 /*@C
5081    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
5082         row of the matrix
5083 
5084    Logically Collective on Mat
5085 
5086    Input Parameter:
5087 .  mat - the matrix
5088 
5089    Output Parameters:
5090 +  v - the vector for storing the maximums
5091 -  idx - the indices of the column found for each row (or NULL if not needed)
5092 
5093    Level: intermediate
5094 
5095    Notes:
5096     if a row is completely empty or has only 0.0 values then the idx[] value for that
5097     row is 0 (the first column).
5098 
5099     This code is only implemented for a couple of matrix formats.
5100 
5101 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5102 @*/
5103 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
5104 {
5105   PetscErrorCode ierr;
5106 
5107   PetscFunctionBegin;
5108   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5109   PetscValidType(mat,1);
5110   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5111   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5112 
5113   if (!mat->cmap->N) {
5114     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5115     if (idx) {
5116       PetscInt i,m = mat->rmap->n;
5117       for (i=0; i<m; i++) idx[i] = -1;
5118     }
5119   } else {
5120     if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5121     MatCheckPreallocated(mat,1);
5122     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5123     ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
5124   }
5125   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5126   PetscFunctionReturn(0);
5127 }
5128 
5129 /*@
5130    MatGetRowSum - Gets the sum of each row of the matrix
5131 
5132    Logically or Neighborhood Collective on Mat
5133 
5134    Input Parameters:
5135 .  mat - the matrix
5136 
5137    Output Parameter:
5138 .  v - the vector for storing the sum of rows
5139 
5140    Level: intermediate
5141 
5142    Notes:
5143     This code is slow since it is not currently specialized for different formats
5144 
5145 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5146 @*/
5147 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
5148 {
5149   Vec            ones;
5150   PetscErrorCode ierr;
5151 
5152   PetscFunctionBegin;
5153   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5154   PetscValidType(mat,1);
5155   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5156   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5157   MatCheckPreallocated(mat,1);
5158   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
5159   ierr = VecSet(ones,1.);CHKERRQ(ierr);
5160   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
5161   ierr = VecDestroy(&ones);CHKERRQ(ierr);
5162   PetscFunctionReturn(0);
5163 }
5164 
5165 /*@
5166    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
5167 
5168    Collective on Mat
5169 
5170    Input Parameters:
5171 +  mat - the matrix to transpose
5172 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5173 
5174    Output Parameter:
5175 .  B - the transpose
5176 
5177    Notes:
5178      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
5179 
5180      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
5181 
5182      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
5183 
5184    Level: intermediate
5185 
5186 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5187 @*/
5188 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
5189 {
5190   PetscErrorCode ierr;
5191 
5192   PetscFunctionBegin;
5193   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5194   PetscValidType(mat,1);
5195   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5196   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5197   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5198   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
5199   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
5200   MatCheckPreallocated(mat,1);
5201 
5202   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5203   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
5204   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5205   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
5206   PetscFunctionReturn(0);
5207 }
5208 
5209 /*@
5210    MatIsTranspose - Test whether a matrix is another one's transpose,
5211         or its own, in which case it tests symmetry.
5212 
5213    Collective on Mat
5214 
5215    Input Parameters:
5216 +  A - the matrix to test
5217 -  B - the matrix to test against, this can equal the first parameter
5218 
5219    Output Parameters:
5220 .  flg - the result
5221 
5222    Notes:
5223    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5224    has a running time of the order of the number of nonzeros; the parallel
5225    test involves parallel copies of the block-offdiagonal parts of the matrix.
5226 
5227    Level: intermediate
5228 
5229 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
5230 @*/
5231 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5232 {
5233   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5234 
5235   PetscFunctionBegin;
5236   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5237   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5238   PetscValidBoolPointer(flg,4);
5239   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5240   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5241   *flg = PETSC_FALSE;
5242   if (f && g) {
5243     if (f == g) {
5244       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5245     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5246   } else {
5247     MatType mattype;
5248     if (!f) {
5249       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5250     } else {
5251       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5252     }
5253     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
5254   }
5255   PetscFunctionReturn(0);
5256 }
5257 
5258 /*@
5259    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5260 
5261    Collective on Mat
5262 
5263    Input Parameters:
5264 +  mat - the matrix to transpose and complex conjugate
5265 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5266 
5267    Output Parameter:
5268 .  B - the Hermitian
5269 
5270    Level: intermediate
5271 
5272 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5273 @*/
5274 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5275 {
5276   PetscErrorCode ierr;
5277 
5278   PetscFunctionBegin;
5279   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5280 #if defined(PETSC_USE_COMPLEX)
5281   ierr = MatConjugate(*B);CHKERRQ(ierr);
5282 #endif
5283   PetscFunctionReturn(0);
5284 }
5285 
5286 /*@
5287    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5288 
5289    Collective on Mat
5290 
5291    Input Parameters:
5292 +  A - the matrix to test
5293 -  B - the matrix to test against, this can equal the first parameter
5294 
5295    Output Parameters:
5296 .  flg - the result
5297 
5298    Notes:
5299    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5300    has a running time of the order of the number of nonzeros; the parallel
5301    test involves parallel copies of the block-offdiagonal parts of the matrix.
5302 
5303    Level: intermediate
5304 
5305 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5306 @*/
5307 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5308 {
5309   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5310 
5311   PetscFunctionBegin;
5312   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5313   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5314   PetscValidBoolPointer(flg,4);
5315   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5316   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5317   if (f && g) {
5318     if (f==g) {
5319       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5320     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5321   }
5322   PetscFunctionReturn(0);
5323 }
5324 
5325 /*@
5326    MatPermute - Creates a new matrix with rows and columns permuted from the
5327    original.
5328 
5329    Collective on Mat
5330 
5331    Input Parameters:
5332 +  mat - the matrix to permute
5333 .  row - row permutation, each processor supplies only the permutation for its rows
5334 -  col - column permutation, each processor supplies only the permutation for its columns
5335 
5336    Output Parameters:
5337 .  B - the permuted matrix
5338 
5339    Level: advanced
5340 
5341    Note:
5342    The index sets map from row/col of permuted matrix to row/col of original matrix.
5343    The index sets should be on the same communicator as Mat and have the same local sizes.
5344 
5345    Developer Note:
5346      If you want to implement MatPermute for a matrix type, and your approach doesn't
5347      exploit the fact that row and col are permutations, consider implementing the
5348      more general MatCreateSubMatrix() instead.
5349 
5350 .seealso: MatGetOrdering(), ISAllGather()
5351 
5352 @*/
5353 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5354 {
5355   PetscErrorCode ierr;
5356 
5357   PetscFunctionBegin;
5358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5359   PetscValidType(mat,1);
5360   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5361   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5362   PetscValidPointer(B,4);
5363   PetscCheckSameComm(mat,1,row,2);
5364   if (row != col) PetscCheckSameComm(row,2,col,3);
5365   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5366   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5367   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);
5368   MatCheckPreallocated(mat,1);
5369 
5370   if (mat->ops->permute) {
5371     ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5372     ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5373   } else {
5374     ierr = MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B);CHKERRQ(ierr);
5375   }
5376   PetscFunctionReturn(0);
5377 }
5378 
5379 /*@
5380    MatEqual - Compares two matrices.
5381 
5382    Collective on Mat
5383 
5384    Input Parameters:
5385 +  A - the first matrix
5386 -  B - the second matrix
5387 
5388    Output Parameter:
5389 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5390 
5391    Level: intermediate
5392 
5393 @*/
5394 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5395 {
5396   PetscErrorCode ierr;
5397 
5398   PetscFunctionBegin;
5399   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5400   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5401   PetscValidType(A,1);
5402   PetscValidType(B,2);
5403   PetscValidBoolPointer(flg,3);
5404   PetscCheckSameComm(A,1,B,2);
5405   MatCheckPreallocated(B,2);
5406   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5407   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5408   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);
5409   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5410   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5411   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);
5412   MatCheckPreallocated(A,1);
5413 
5414   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5415   PetscFunctionReturn(0);
5416 }
5417 
5418 /*@
5419    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5420    matrices that are stored as vectors.  Either of the two scaling
5421    matrices can be NULL.
5422 
5423    Collective on Mat
5424 
5425    Input Parameters:
5426 +  mat - the matrix to be scaled
5427 .  l - the left scaling vector (or NULL)
5428 -  r - the right scaling vector (or NULL)
5429 
5430    Notes:
5431    MatDiagonalScale() computes A = LAR, where
5432    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5433    The L scales the rows of the matrix, the R scales the columns of the matrix.
5434 
5435    Level: intermediate
5436 
5437 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5438 @*/
5439 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5440 {
5441   PetscErrorCode ierr;
5442 
5443   PetscFunctionBegin;
5444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5445   PetscValidType(mat,1);
5446   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5447   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5448   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5449   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5450   MatCheckPreallocated(mat,1);
5451   if (!l && !r) PetscFunctionReturn(0);
5452 
5453   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5454   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5455   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5456   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5457   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5458   PetscFunctionReturn(0);
5459 }
5460 
5461 /*@
5462     MatScale - Scales all elements of a matrix by a given number.
5463 
5464     Logically Collective on Mat
5465 
5466     Input Parameters:
5467 +   mat - the matrix to be scaled
5468 -   a  - the scaling value
5469 
5470     Output Parameter:
5471 .   mat - the scaled matrix
5472 
5473     Level: intermediate
5474 
5475 .seealso: MatDiagonalScale()
5476 @*/
5477 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5478 {
5479   PetscErrorCode ierr;
5480 
5481   PetscFunctionBegin;
5482   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5483   PetscValidType(mat,1);
5484   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5485   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5486   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5487   PetscValidLogicalCollectiveScalar(mat,a,2);
5488   MatCheckPreallocated(mat,1);
5489 
5490   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5491   if (a != (PetscScalar)1.0) {
5492     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5493     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5494   }
5495   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5496   PetscFunctionReturn(0);
5497 }
5498 
5499 /*@
5500    MatNorm - Calculates various norms of a matrix.
5501 
5502    Collective on Mat
5503 
5504    Input Parameters:
5505 +  mat - the matrix
5506 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5507 
5508    Output Parameter:
5509 .  nrm - the resulting norm
5510 
5511    Level: intermediate
5512 
5513 @*/
5514 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5515 {
5516   PetscErrorCode ierr;
5517 
5518   PetscFunctionBegin;
5519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5520   PetscValidType(mat,1);
5521   PetscValidRealPointer(nrm,3);
5522 
5523   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5524   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5525   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5526   MatCheckPreallocated(mat,1);
5527 
5528   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5529   PetscFunctionReturn(0);
5530 }
5531 
5532 /*
5533      This variable is used to prevent counting of MatAssemblyBegin() that
5534    are called from within a MatAssemblyEnd().
5535 */
5536 static PetscInt MatAssemblyEnd_InUse = 0;
5537 /*@
5538    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5539    be called after completing all calls to MatSetValues().
5540 
5541    Collective on Mat
5542 
5543    Input Parameters:
5544 +  mat - the matrix
5545 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5546 
5547    Notes:
5548    MatSetValues() generally caches the values.  The matrix is ready to
5549    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5550    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5551    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5552    using the matrix.
5553 
5554    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5555    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
5556    a global collective operation requring all processes that share the matrix.
5557 
5558    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5559    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5560    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5561 
5562    Level: beginner
5563 
5564 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5565 @*/
5566 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5567 {
5568   PetscErrorCode ierr;
5569 
5570   PetscFunctionBegin;
5571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5572   PetscValidType(mat,1);
5573   MatCheckPreallocated(mat,1);
5574   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5575   if (mat->assembled) {
5576     mat->was_assembled = PETSC_TRUE;
5577     mat->assembled     = PETSC_FALSE;
5578   }
5579 
5580   if (!MatAssemblyEnd_InUse) {
5581     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5582     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5583     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5584   } else if (mat->ops->assemblybegin) {
5585     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5586   }
5587   PetscFunctionReturn(0);
5588 }
5589 
5590 /*@
5591    MatAssembled - Indicates if a matrix has been assembled and is ready for
5592      use; for example, in matrix-vector product.
5593 
5594    Not Collective
5595 
5596    Input Parameter:
5597 .  mat - the matrix
5598 
5599    Output Parameter:
5600 .  assembled - PETSC_TRUE or PETSC_FALSE
5601 
5602    Level: advanced
5603 
5604 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5605 @*/
5606 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5607 {
5608   PetscFunctionBegin;
5609   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5610   PetscValidPointer(assembled,2);
5611   *assembled = mat->assembled;
5612   PetscFunctionReturn(0);
5613 }
5614 
5615 /*@
5616    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5617    be called after MatAssemblyBegin().
5618 
5619    Collective on Mat
5620 
5621    Input Parameters:
5622 +  mat - the matrix
5623 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5624 
5625    Options Database Keys:
5626 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5627 .  -mat_view ::ascii_info_detail - Prints more detailed info
5628 .  -mat_view - Prints matrix in ASCII format
5629 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5630 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5631 .  -display <name> - Sets display name (default is host)
5632 .  -draw_pause <sec> - Sets number of seconds to pause after display
5633 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab)
5634 .  -viewer_socket_machine <machine> - Machine to use for socket
5635 .  -viewer_socket_port <port> - Port number to use for socket
5636 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5637 
5638    Notes:
5639    MatSetValues() generally caches the values.  The matrix is ready to
5640    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5641    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5642    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5643    using the matrix.
5644 
5645    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5646    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5647    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5648 
5649    Level: beginner
5650 
5651 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5652 @*/
5653 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5654 {
5655   PetscErrorCode  ierr;
5656   static PetscInt inassm = 0;
5657   PetscBool       flg    = PETSC_FALSE;
5658 
5659   PetscFunctionBegin;
5660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5661   PetscValidType(mat,1);
5662 
5663   inassm++;
5664   MatAssemblyEnd_InUse++;
5665   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5666     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5667     if (mat->ops->assemblyend) {
5668       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5669     }
5670     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5671   } else if (mat->ops->assemblyend) {
5672     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5673   }
5674 
5675   /* Flush assembly is not a true assembly */
5676   if (type != MAT_FLUSH_ASSEMBLY) {
5677     mat->num_ass++;
5678     mat->assembled        = PETSC_TRUE;
5679     mat->ass_nonzerostate = mat->nonzerostate;
5680   }
5681 
5682   mat->insertmode = NOT_SET_VALUES;
5683   MatAssemblyEnd_InUse--;
5684   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5685   if (!mat->symmetric_eternal) {
5686     mat->symmetric_set              = PETSC_FALSE;
5687     mat->hermitian_set              = PETSC_FALSE;
5688     mat->structurally_symmetric_set = PETSC_FALSE;
5689   }
5690   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5691     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5692 
5693     if (mat->checksymmetryonassembly) {
5694       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5695       if (flg) {
5696         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5697       } else {
5698         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5699       }
5700     }
5701     if (mat->nullsp && mat->checknullspaceonassembly) {
5702       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5703     }
5704   }
5705   inassm--;
5706   PetscFunctionReturn(0);
5707 }
5708 
5709 /*@
5710    MatSetOption - Sets a parameter option for a matrix. Some options
5711    may be specific to certain storage formats.  Some options
5712    determine how values will be inserted (or added). Sorted,
5713    row-oriented input will generally assemble the fastest. The default
5714    is row-oriented.
5715 
5716    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5717 
5718    Input Parameters:
5719 +  mat - the matrix
5720 .  option - the option, one of those listed below (and possibly others),
5721 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5722 
5723   Options Describing Matrix Structure:
5724 +    MAT_SPD - symmetric positive definite
5725 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5726 .    MAT_HERMITIAN - transpose is the complex conjugation
5727 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5728 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5729                             you set to be kept with all future use of the matrix
5730                             including after MatAssemblyBegin/End() which could
5731                             potentially change the symmetry structure, i.e. you
5732                             KNOW the matrix will ALWAYS have the property you set.
5733                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5734                             the relevant flags must be set independently.
5735 
5736    Options For Use with MatSetValues():
5737    Insert a logically dense subblock, which can be
5738 .    MAT_ROW_ORIENTED - row-oriented (default)
5739 
5740    Note these options reflect the data you pass in with MatSetValues(); it has
5741    nothing to do with how the data is stored internally in the matrix
5742    data structure.
5743 
5744    When (re)assembling a matrix, we can restrict the input for
5745    efficiency/debugging purposes.  These options include:
5746 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5747 .    MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated
5748 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5749 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5750 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5751 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5752         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5753         performance for very large process counts.
5754 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5755         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5756         functions, instead sending only neighbor messages.
5757 
5758    Notes:
5759    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5760 
5761    Some options are relevant only for particular matrix types and
5762    are thus ignored by others.  Other options are not supported by
5763    certain matrix types and will generate an error message if set.
5764 
5765    If using a Fortran 77 module to compute a matrix, one may need to
5766    use the column-oriented option (or convert to the row-oriented
5767    format).
5768 
5769    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5770    that would generate a new entry in the nonzero structure is instead
5771    ignored.  Thus, if memory has not alredy been allocated for this particular
5772    data, then the insertion is ignored. For dense matrices, in which
5773    the entire array is allocated, no entries are ever ignored.
5774    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5775 
5776    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5777    that would generate a new entry in the nonzero structure instead produces
5778    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
5779 
5780    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5781    that would generate a new entry that has not been preallocated will
5782    instead produce an error. (Currently supported for AIJ and BAIJ formats
5783    only.) This is a useful flag when debugging matrix memory preallocation.
5784    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5785 
5786    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5787    other processors should be dropped, rather than stashed.
5788    This is useful if you know that the "owning" processor is also
5789    always generating the correct matrix entries, so that PETSc need
5790    not transfer duplicate entries generated on another processor.
5791 
5792    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5793    searches during matrix assembly. When this flag is set, the hash table
5794    is created during the first Matrix Assembly. This hash table is
5795    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5796    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5797    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5798    supported by MATMPIBAIJ format only.
5799 
5800    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5801    are kept in the nonzero structure
5802 
5803    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5804    a zero location in the matrix
5805 
5806    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5807 
5808    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5809         zero row routines and thus improves performance for very large process counts.
5810 
5811    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5812         part of the matrix (since they should match the upper triangular part).
5813 
5814    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5815                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5816                      with finite difference schemes with non-periodic boundary conditions.
5817 
5818    Level: intermediate
5819 
5820 .seealso:  MatOption, Mat
5821 
5822 @*/
5823 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5824 {
5825   PetscErrorCode ierr;
5826 
5827   PetscFunctionBegin;
5828   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5829   if (op > 0) {
5830     PetscValidLogicalCollectiveEnum(mat,op,2);
5831     PetscValidLogicalCollectiveBool(mat,flg,3);
5832   }
5833 
5834   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);
5835 
5836   switch (op) {
5837   case MAT_FORCE_DIAGONAL_ENTRIES:
5838     mat->force_diagonals = flg;
5839     PetscFunctionReturn(0);
5840   case MAT_NO_OFF_PROC_ENTRIES:
5841     mat->nooffprocentries = flg;
5842     PetscFunctionReturn(0);
5843   case MAT_SUBSET_OFF_PROC_ENTRIES:
5844     mat->assembly_subset = flg;
5845     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5846 #if !defined(PETSC_HAVE_MPIUNI)
5847       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5848 #endif
5849       mat->stash.first_assembly_done = PETSC_FALSE;
5850     }
5851     PetscFunctionReturn(0);
5852   case MAT_NO_OFF_PROC_ZERO_ROWS:
5853     mat->nooffproczerorows = flg;
5854     PetscFunctionReturn(0);
5855   case MAT_SPD:
5856     mat->spd_set = PETSC_TRUE;
5857     mat->spd     = flg;
5858     if (flg) {
5859       mat->symmetric                  = PETSC_TRUE;
5860       mat->structurally_symmetric     = PETSC_TRUE;
5861       mat->symmetric_set              = PETSC_TRUE;
5862       mat->structurally_symmetric_set = PETSC_TRUE;
5863     }
5864     break;
5865   case MAT_SYMMETRIC:
5866     mat->symmetric = flg;
5867     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5868     mat->symmetric_set              = PETSC_TRUE;
5869     mat->structurally_symmetric_set = flg;
5870 #if !defined(PETSC_USE_COMPLEX)
5871     mat->hermitian     = flg;
5872     mat->hermitian_set = PETSC_TRUE;
5873 #endif
5874     break;
5875   case MAT_HERMITIAN:
5876     mat->hermitian = flg;
5877     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5878     mat->hermitian_set              = PETSC_TRUE;
5879     mat->structurally_symmetric_set = flg;
5880 #if !defined(PETSC_USE_COMPLEX)
5881     mat->symmetric     = flg;
5882     mat->symmetric_set = PETSC_TRUE;
5883 #endif
5884     break;
5885   case MAT_STRUCTURALLY_SYMMETRIC:
5886     mat->structurally_symmetric     = flg;
5887     mat->structurally_symmetric_set = PETSC_TRUE;
5888     break;
5889   case MAT_SYMMETRY_ETERNAL:
5890     mat->symmetric_eternal = flg;
5891     break;
5892   case MAT_STRUCTURE_ONLY:
5893     mat->structure_only = flg;
5894     break;
5895   case MAT_SORTED_FULL:
5896     mat->sortedfull = flg;
5897     break;
5898   default:
5899     break;
5900   }
5901   if (mat->ops->setoption) {
5902     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5903   }
5904   PetscFunctionReturn(0);
5905 }
5906 
5907 /*@
5908    MatGetOption - Gets a parameter option that has been set for a matrix.
5909 
5910    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5911 
5912    Input Parameters:
5913 +  mat - the matrix
5914 -  option - the option, this only responds to certain options, check the code for which ones
5915 
5916    Output Parameter:
5917 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5918 
5919     Notes:
5920     Can only be called after MatSetSizes() and MatSetType() have been set.
5921 
5922    Level: intermediate
5923 
5924 .seealso:  MatOption, MatSetOption()
5925 
5926 @*/
5927 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5928 {
5929   PetscFunctionBegin;
5930   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5931   PetscValidType(mat,1);
5932 
5933   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);
5934   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()");
5935 
5936   switch (op) {
5937   case MAT_NO_OFF_PROC_ENTRIES:
5938     *flg = mat->nooffprocentries;
5939     break;
5940   case MAT_NO_OFF_PROC_ZERO_ROWS:
5941     *flg = mat->nooffproczerorows;
5942     break;
5943   case MAT_SYMMETRIC:
5944     *flg = mat->symmetric;
5945     break;
5946   case MAT_HERMITIAN:
5947     *flg = mat->hermitian;
5948     break;
5949   case MAT_STRUCTURALLY_SYMMETRIC:
5950     *flg = mat->structurally_symmetric;
5951     break;
5952   case MAT_SYMMETRY_ETERNAL:
5953     *flg = mat->symmetric_eternal;
5954     break;
5955   case MAT_SPD:
5956     *flg = mat->spd;
5957     break;
5958   default:
5959     break;
5960   }
5961   PetscFunctionReturn(0);
5962 }
5963 
5964 /*@
5965    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5966    this routine retains the old nonzero structure.
5967 
5968    Logically Collective on Mat
5969 
5970    Input Parameters:
5971 .  mat - the matrix
5972 
5973    Level: intermediate
5974 
5975    Notes:
5976     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.
5977    See the Performance chapter of the users manual for information on preallocating matrices.
5978 
5979 .seealso: MatZeroRows()
5980 @*/
5981 PetscErrorCode MatZeroEntries(Mat mat)
5982 {
5983   PetscErrorCode ierr;
5984 
5985   PetscFunctionBegin;
5986   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5987   PetscValidType(mat,1);
5988   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5989   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");
5990   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5991   MatCheckPreallocated(mat,1);
5992 
5993   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5994   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5995   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5996   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5997   PetscFunctionReturn(0);
5998 }
5999 
6000 /*@
6001    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
6002    of a set of rows and columns of a matrix.
6003 
6004    Collective on Mat
6005 
6006    Input Parameters:
6007 +  mat - the matrix
6008 .  numRows - the number of rows to remove
6009 .  rows - the global row indices
6010 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6011 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6012 -  b - optional vector of right hand side, that will be adjusted by provided solution
6013 
6014    Notes:
6015    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6016 
6017    The user can set a value in the diagonal entry (or for the AIJ and
6018    row formats can optionally remove the main diagonal entry from the
6019    nonzero structure as well, by passing 0.0 as the final argument).
6020 
6021    For the parallel case, all processes that share the matrix (i.e.,
6022    those in the communicator used for matrix creation) MUST call this
6023    routine, regardless of whether any rows being zeroed are owned by
6024    them.
6025 
6026    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6027    list only rows local to itself).
6028 
6029    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6030 
6031    Level: intermediate
6032 
6033 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6034           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6035 @*/
6036 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6037 {
6038   PetscErrorCode ierr;
6039 
6040   PetscFunctionBegin;
6041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6042   PetscValidType(mat,1);
6043   if (numRows) PetscValidIntPointer(rows,3);
6044   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6045   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6046   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6047   MatCheckPreallocated(mat,1);
6048 
6049   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6050   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6051   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6052   PetscFunctionReturn(0);
6053 }
6054 
6055 /*@
6056    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
6057    of a set of rows and columns of a matrix.
6058 
6059    Collective on Mat
6060 
6061    Input Parameters:
6062 +  mat - the matrix
6063 .  is - the rows to zero
6064 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6065 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6066 -  b - optional vector of right hand side, that will be adjusted by provided solution
6067 
6068    Notes:
6069    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6070 
6071    The user can set a value in the diagonal entry (or for the AIJ and
6072    row formats can optionally remove the main diagonal entry from the
6073    nonzero structure as well, by passing 0.0 as the final argument).
6074 
6075    For the parallel case, all processes that share the matrix (i.e.,
6076    those in the communicator used for matrix creation) MUST call this
6077    routine, regardless of whether any rows being zeroed are owned by
6078    them.
6079 
6080    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6081    list only rows local to itself).
6082 
6083    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6084 
6085    Level: intermediate
6086 
6087 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6088           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
6089 @*/
6090 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6091 {
6092   PetscErrorCode ierr;
6093   PetscInt       numRows;
6094   const PetscInt *rows;
6095 
6096   PetscFunctionBegin;
6097   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6098   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6099   PetscValidType(mat,1);
6100   PetscValidType(is,2);
6101   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6102   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6103   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6104   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6105   PetscFunctionReturn(0);
6106 }
6107 
6108 /*@
6109    MatZeroRows - Zeros all entries (except possibly the main diagonal)
6110    of a set of rows of a matrix.
6111 
6112    Collective on Mat
6113 
6114    Input Parameters:
6115 +  mat - the matrix
6116 .  numRows - the number of rows to remove
6117 .  rows - the global row indices
6118 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6119 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6120 -  b - optional vector of right hand side, that will be adjusted by provided solution
6121 
6122    Notes:
6123    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6124    but does not release memory.  For the dense and block diagonal
6125    formats this does not alter the nonzero structure.
6126 
6127    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6128    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6129    merely zeroed.
6130 
6131    The user can set a value in the diagonal entry (or for the AIJ and
6132    row formats can optionally remove the main diagonal entry from the
6133    nonzero structure as well, by passing 0.0 as the final argument).
6134 
6135    For the parallel case, all processes that share the matrix (i.e.,
6136    those in the communicator used for matrix creation) MUST call this
6137    routine, regardless of whether any rows being zeroed are owned by
6138    them.
6139 
6140    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6141    list only rows local to itself).
6142 
6143    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6144    owns that are to be zeroed. This saves a global synchronization in the implementation.
6145 
6146    Level: intermediate
6147 
6148 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6149           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6150 @*/
6151 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6152 {
6153   PetscErrorCode ierr;
6154 
6155   PetscFunctionBegin;
6156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6157   PetscValidType(mat,1);
6158   if (numRows) PetscValidIntPointer(rows,3);
6159   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6160   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6161   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6162   MatCheckPreallocated(mat,1);
6163 
6164   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6165   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6166   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6167   PetscFunctionReturn(0);
6168 }
6169 
6170 /*@
6171    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
6172    of a set of rows of a matrix.
6173 
6174    Collective on Mat
6175 
6176    Input Parameters:
6177 +  mat - the matrix
6178 .  is - index set of rows to remove (if NULL then no row is removed)
6179 .  diag - value put in all diagonals of eliminated rows
6180 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6181 -  b - optional vector of right hand side, that will be adjusted by provided solution
6182 
6183    Notes:
6184    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6185    but does not release memory.  For the dense and block diagonal
6186    formats this does not alter the nonzero structure.
6187 
6188    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6189    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6190    merely zeroed.
6191 
6192    The user can set a value in the diagonal entry (or for the AIJ and
6193    row formats can optionally remove the main diagonal entry from the
6194    nonzero structure as well, by passing 0.0 as the final argument).
6195 
6196    For the parallel case, all processes that share the matrix (i.e.,
6197    those in the communicator used for matrix creation) MUST call this
6198    routine, regardless of whether any rows being zeroed are owned by
6199    them.
6200 
6201    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6202    list only rows local to itself).
6203 
6204    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6205    owns that are to be zeroed. This saves a global synchronization in the implementation.
6206 
6207    Level: intermediate
6208 
6209 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6210           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6211 @*/
6212 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6213 {
6214   PetscInt       numRows = 0;
6215   const PetscInt *rows = NULL;
6216   PetscErrorCode ierr;
6217 
6218   PetscFunctionBegin;
6219   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6220   PetscValidType(mat,1);
6221   if (is) {
6222     PetscValidHeaderSpecific(is,IS_CLASSID,2);
6223     ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6224     ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6225   }
6226   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6227   if (is) {
6228     ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6229   }
6230   PetscFunctionReturn(0);
6231 }
6232 
6233 /*@
6234    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6235    of a set of rows of a matrix. These rows must be local to the process.
6236 
6237    Collective on Mat
6238 
6239    Input Parameters:
6240 +  mat - the matrix
6241 .  numRows - the number of rows to remove
6242 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6243 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6244 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6245 -  b - optional vector of right hand side, that will be adjusted by provided solution
6246 
6247    Notes:
6248    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6249    but does not release memory.  For the dense and block diagonal
6250    formats this does not alter the nonzero structure.
6251 
6252    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6253    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6254    merely zeroed.
6255 
6256    The user can set a value in the diagonal entry (or for the AIJ and
6257    row formats can optionally remove the main diagonal entry from the
6258    nonzero structure as well, by passing 0.0 as the final argument).
6259 
6260    For the parallel case, all processes that share the matrix (i.e.,
6261    those in the communicator used for matrix creation) MUST call this
6262    routine, regardless of whether any rows being zeroed are owned by
6263    them.
6264 
6265    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6266    list only rows local to itself).
6267 
6268    The grid coordinates are across the entire grid, not just the local portion
6269 
6270    In Fortran idxm and idxn should be declared as
6271 $     MatStencil idxm(4,m)
6272    and the values inserted using
6273 $    idxm(MatStencil_i,1) = i
6274 $    idxm(MatStencil_j,1) = j
6275 $    idxm(MatStencil_k,1) = k
6276 $    idxm(MatStencil_c,1) = c
6277    etc
6278 
6279    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6280    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6281    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6282    DM_BOUNDARY_PERIODIC boundary type.
6283 
6284    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
6285    a single value per point) you can skip filling those indices.
6286 
6287    Level: intermediate
6288 
6289 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6290           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6291 @*/
6292 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6293 {
6294   PetscInt       dim     = mat->stencil.dim;
6295   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6296   PetscInt       *dims   = mat->stencil.dims+1;
6297   PetscInt       *starts = mat->stencil.starts;
6298   PetscInt       *dxm    = (PetscInt*) rows;
6299   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6300   PetscErrorCode ierr;
6301 
6302   PetscFunctionBegin;
6303   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6304   PetscValidType(mat,1);
6305   if (numRows) PetscValidPointer(rows,3);
6306 
6307   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6308   for (i = 0; i < numRows; ++i) {
6309     /* Skip unused dimensions (they are ordered k, j, i, c) */
6310     for (j = 0; j < 3-sdim; ++j) dxm++;
6311     /* Local index in X dir */
6312     tmp = *dxm++ - starts[0];
6313     /* Loop over remaining dimensions */
6314     for (j = 0; j < dim-1; ++j) {
6315       /* If nonlocal, set index to be negative */
6316       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6317       /* Update local index */
6318       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6319     }
6320     /* Skip component slot if necessary */
6321     if (mat->stencil.noc) dxm++;
6322     /* Local row number */
6323     if (tmp >= 0) {
6324       jdxm[numNewRows++] = tmp;
6325     }
6326   }
6327   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6328   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6329   PetscFunctionReturn(0);
6330 }
6331 
6332 /*@
6333    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6334    of a set of rows and columns of a matrix.
6335 
6336    Collective on Mat
6337 
6338    Input Parameters:
6339 +  mat - the matrix
6340 .  numRows - the number of rows/columns to remove
6341 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6342 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6343 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6344 -  b - optional vector of right hand side, that will be adjusted by provided solution
6345 
6346    Notes:
6347    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6348    but does not release memory.  For the dense and block diagonal
6349    formats this does not alter the nonzero structure.
6350 
6351    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6352    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6353    merely zeroed.
6354 
6355    The user can set a value in the diagonal entry (or for the AIJ and
6356    row formats can optionally remove the main diagonal entry from the
6357    nonzero structure as well, by passing 0.0 as the final argument).
6358 
6359    For the parallel case, all processes that share the matrix (i.e.,
6360    those in the communicator used for matrix creation) MUST call this
6361    routine, regardless of whether any rows being zeroed are owned by
6362    them.
6363 
6364    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6365    list only rows local to itself, but the row/column numbers are given in local numbering).
6366 
6367    The grid coordinates are across the entire grid, not just the local portion
6368 
6369    In Fortran idxm and idxn should be declared as
6370 $     MatStencil idxm(4,m)
6371    and the values inserted using
6372 $    idxm(MatStencil_i,1) = i
6373 $    idxm(MatStencil_j,1) = j
6374 $    idxm(MatStencil_k,1) = k
6375 $    idxm(MatStencil_c,1) = c
6376    etc
6377 
6378    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6379    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6380    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6381    DM_BOUNDARY_PERIODIC boundary type.
6382 
6383    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
6384    a single value per point) you can skip filling those indices.
6385 
6386    Level: intermediate
6387 
6388 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6389           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6390 @*/
6391 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6392 {
6393   PetscInt       dim     = mat->stencil.dim;
6394   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6395   PetscInt       *dims   = mat->stencil.dims+1;
6396   PetscInt       *starts = mat->stencil.starts;
6397   PetscInt       *dxm    = (PetscInt*) rows;
6398   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6399   PetscErrorCode ierr;
6400 
6401   PetscFunctionBegin;
6402   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6403   PetscValidType(mat,1);
6404   if (numRows) PetscValidPointer(rows,3);
6405 
6406   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6407   for (i = 0; i < numRows; ++i) {
6408     /* Skip unused dimensions (they are ordered k, j, i, c) */
6409     for (j = 0; j < 3-sdim; ++j) dxm++;
6410     /* Local index in X dir */
6411     tmp = *dxm++ - starts[0];
6412     /* Loop over remaining dimensions */
6413     for (j = 0; j < dim-1; ++j) {
6414       /* If nonlocal, set index to be negative */
6415       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6416       /* Update local index */
6417       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6418     }
6419     /* Skip component slot if necessary */
6420     if (mat->stencil.noc) dxm++;
6421     /* Local row number */
6422     if (tmp >= 0) {
6423       jdxm[numNewRows++] = tmp;
6424     }
6425   }
6426   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6427   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6428   PetscFunctionReturn(0);
6429 }
6430 
6431 /*@C
6432    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6433    of a set of rows of a matrix; using local numbering of rows.
6434 
6435    Collective on Mat
6436 
6437    Input Parameters:
6438 +  mat - the matrix
6439 .  numRows - the number of rows to remove
6440 .  rows - the local row indices
6441 .  diag - value put in all diagonals of eliminated rows
6442 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6443 -  b - optional vector of right hand side, that will be adjusted by provided solution
6444 
6445    Notes:
6446    Before calling MatZeroRowsLocal(), the user must first set the
6447    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6448 
6449    For the AIJ matrix formats this removes the old nonzero structure,
6450    but does not release memory.  For the dense and block diagonal
6451    formats this does not alter the nonzero structure.
6452 
6453    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6454    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6455    merely zeroed.
6456 
6457    The user can set a value in the diagonal entry (or for the AIJ and
6458    row formats can optionally remove the main diagonal entry from the
6459    nonzero structure as well, by passing 0.0 as the final argument).
6460 
6461    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6462    owns that are to be zeroed. This saves a global synchronization in the implementation.
6463 
6464    Level: intermediate
6465 
6466 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6467           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6468 @*/
6469 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6470 {
6471   PetscErrorCode ierr;
6472 
6473   PetscFunctionBegin;
6474   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6475   PetscValidType(mat,1);
6476   if (numRows) PetscValidIntPointer(rows,3);
6477   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6478   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6479   MatCheckPreallocated(mat,1);
6480 
6481   if (mat->ops->zerorowslocal) {
6482     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6483   } else {
6484     IS             is, newis;
6485     const PetscInt *newRows;
6486 
6487     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6488     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6489     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6490     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6491     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6492     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6493     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6494     ierr = ISDestroy(&is);CHKERRQ(ierr);
6495   }
6496   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6497   PetscFunctionReturn(0);
6498 }
6499 
6500 /*@
6501    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6502    of a set of rows of a matrix; using local numbering of rows.
6503 
6504    Collective on Mat
6505 
6506    Input Parameters:
6507 +  mat - the matrix
6508 .  is - index set of rows to remove
6509 .  diag - value put in all diagonals of eliminated rows
6510 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6511 -  b - optional vector of right hand side, that will be adjusted by provided solution
6512 
6513    Notes:
6514    Before calling MatZeroRowsLocalIS(), the user must first set the
6515    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6516 
6517    For the AIJ matrix formats this removes the old nonzero structure,
6518    but does not release memory.  For the dense and block diagonal
6519    formats this does not alter the nonzero structure.
6520 
6521    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6522    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6523    merely zeroed.
6524 
6525    The user can set a value in the diagonal entry (or for the AIJ and
6526    row formats can optionally remove the main diagonal entry from the
6527    nonzero structure as well, by passing 0.0 as the final argument).
6528 
6529    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6530    owns that are to be zeroed. This saves a global synchronization in the implementation.
6531 
6532    Level: intermediate
6533 
6534 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6535           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6536 @*/
6537 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6538 {
6539   PetscErrorCode ierr;
6540   PetscInt       numRows;
6541   const PetscInt *rows;
6542 
6543   PetscFunctionBegin;
6544   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6545   PetscValidType(mat,1);
6546   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6547   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6548   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6549   MatCheckPreallocated(mat,1);
6550 
6551   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6552   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6553   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6554   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6555   PetscFunctionReturn(0);
6556 }
6557 
6558 /*@
6559    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6560    of a set of rows and columns of a matrix; using local numbering of rows.
6561 
6562    Collective on Mat
6563 
6564    Input Parameters:
6565 +  mat - the matrix
6566 .  numRows - the number of rows to remove
6567 .  rows - the global row indices
6568 .  diag - value put in all diagonals of eliminated rows
6569 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6570 -  b - optional vector of right hand side, that will be adjusted by provided solution
6571 
6572    Notes:
6573    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6574    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6575 
6576    The user can set a value in the diagonal entry (or for the AIJ and
6577    row formats can optionally remove the main diagonal entry from the
6578    nonzero structure as well, by passing 0.0 as the final argument).
6579 
6580    Level: intermediate
6581 
6582 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6583           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6584 @*/
6585 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6586 {
6587   PetscErrorCode ierr;
6588   IS             is, newis;
6589   const PetscInt *newRows;
6590 
6591   PetscFunctionBegin;
6592   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6593   PetscValidType(mat,1);
6594   if (numRows) PetscValidIntPointer(rows,3);
6595   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6596   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6597   MatCheckPreallocated(mat,1);
6598 
6599   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6600   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6601   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6602   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6603   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6604   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6605   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6606   ierr = ISDestroy(&is);CHKERRQ(ierr);
6607   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6608   PetscFunctionReturn(0);
6609 }
6610 
6611 /*@
6612    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6613    of a set of rows and columns of a matrix; using local numbering of rows.
6614 
6615    Collective on Mat
6616 
6617    Input Parameters:
6618 +  mat - the matrix
6619 .  is - index set of rows to remove
6620 .  diag - value put in all diagonals of eliminated rows
6621 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6622 -  b - optional vector of right hand side, that will be adjusted by provided solution
6623 
6624    Notes:
6625    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6626    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6627 
6628    The user can set a value in the diagonal entry (or for the AIJ and
6629    row formats can optionally remove the main diagonal entry from the
6630    nonzero structure as well, by passing 0.0 as the final argument).
6631 
6632    Level: intermediate
6633 
6634 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6635           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6636 @*/
6637 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6638 {
6639   PetscErrorCode ierr;
6640   PetscInt       numRows;
6641   const PetscInt *rows;
6642 
6643   PetscFunctionBegin;
6644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6645   PetscValidType(mat,1);
6646   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6647   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6648   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6649   MatCheckPreallocated(mat,1);
6650 
6651   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6652   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6653   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6654   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6655   PetscFunctionReturn(0);
6656 }
6657 
6658 /*@C
6659    MatGetSize - Returns the numbers of rows and columns in a matrix.
6660 
6661    Not Collective
6662 
6663    Input Parameter:
6664 .  mat - the matrix
6665 
6666    Output Parameters:
6667 +  m - the number of global rows
6668 -  n - the number of global columns
6669 
6670    Note: both output parameters can be NULL on input.
6671 
6672    Level: beginner
6673 
6674 .seealso: MatGetLocalSize()
6675 @*/
6676 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6677 {
6678   PetscFunctionBegin;
6679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6680   if (m) *m = mat->rmap->N;
6681   if (n) *n = mat->cmap->N;
6682   PetscFunctionReturn(0);
6683 }
6684 
6685 /*@C
6686    MatGetLocalSize - Returns the number of local rows and local columns
6687    of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs().
6688 
6689    Not Collective
6690 
6691    Input Parameter:
6692 .  mat - the matrix
6693 
6694    Output Parameters:
6695 +  m - the number of local rows
6696 -  n - the number of local columns
6697 
6698    Note: both output parameters can be NULL on input.
6699 
6700    Level: beginner
6701 
6702 .seealso: MatGetSize()
6703 @*/
6704 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6705 {
6706   PetscFunctionBegin;
6707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6708   if (m) PetscValidIntPointer(m,2);
6709   if (n) PetscValidIntPointer(n,3);
6710   if (m) *m = mat->rmap->n;
6711   if (n) *n = mat->cmap->n;
6712   PetscFunctionReturn(0);
6713 }
6714 
6715 /*@C
6716    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6717    this processor. (The columns of the "diagonal block")
6718 
6719    Not Collective, unless matrix has not been allocated, then collective on Mat
6720 
6721    Input Parameter:
6722 .  mat - the matrix
6723 
6724    Output Parameters:
6725 +  m - the global index of the first local column
6726 -  n - one more than the global index of the last local column
6727 
6728    Notes:
6729     both output parameters can be NULL on input.
6730 
6731    Level: developer
6732 
6733 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6734 
6735 @*/
6736 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6737 {
6738   PetscFunctionBegin;
6739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6740   PetscValidType(mat,1);
6741   if (m) PetscValidIntPointer(m,2);
6742   if (n) PetscValidIntPointer(n,3);
6743   MatCheckPreallocated(mat,1);
6744   if (m) *m = mat->cmap->rstart;
6745   if (n) *n = mat->cmap->rend;
6746   PetscFunctionReturn(0);
6747 }
6748 
6749 /*@C
6750    MatGetOwnershipRange - Returns the range of matrix rows owned by
6751    this processor, assuming that the matrix is laid out with the first
6752    n1 rows on the first processor, the next n2 rows on the second, etc.
6753    For certain parallel layouts this range may not be well defined.
6754 
6755    Not Collective
6756 
6757    Input Parameter:
6758 .  mat - the matrix
6759 
6760    Output Parameters:
6761 +  m - the global index of the first local row
6762 -  n - one more than the global index of the last local row
6763 
6764    Note: Both output parameters can be NULL on input.
6765 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6766 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6767 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6768 
6769    Level: beginner
6770 
6771 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6772 
6773 @*/
6774 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6775 {
6776   PetscFunctionBegin;
6777   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6778   PetscValidType(mat,1);
6779   if (m) PetscValidIntPointer(m,2);
6780   if (n) PetscValidIntPointer(n,3);
6781   MatCheckPreallocated(mat,1);
6782   if (m) *m = mat->rmap->rstart;
6783   if (n) *n = mat->rmap->rend;
6784   PetscFunctionReturn(0);
6785 }
6786 
6787 /*@C
6788    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6789    each process
6790 
6791    Not Collective, unless matrix has not been allocated, then collective on Mat
6792 
6793    Input Parameters:
6794 .  mat - the matrix
6795 
6796    Output Parameters:
6797 .  ranges - start of each processors portion plus one more than the total length at the end
6798 
6799    Level: beginner
6800 
6801 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6802 
6803 @*/
6804 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6805 {
6806   PetscErrorCode ierr;
6807 
6808   PetscFunctionBegin;
6809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6810   PetscValidType(mat,1);
6811   MatCheckPreallocated(mat,1);
6812   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6813   PetscFunctionReturn(0);
6814 }
6815 
6816 /*@C
6817    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6818    this processor. (The columns of the "diagonal blocks" for each process)
6819 
6820    Not Collective, unless matrix has not been allocated, then collective on Mat
6821 
6822    Input Parameters:
6823 .  mat - the matrix
6824 
6825    Output Parameters:
6826 .  ranges - start of each processors portion plus one more then the total length at the end
6827 
6828    Level: beginner
6829 
6830 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6831 
6832 @*/
6833 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6834 {
6835   PetscErrorCode ierr;
6836 
6837   PetscFunctionBegin;
6838   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6839   PetscValidType(mat,1);
6840   MatCheckPreallocated(mat,1);
6841   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6842   PetscFunctionReturn(0);
6843 }
6844 
6845 /*@C
6846    MatGetOwnershipIS - Get row and column ownership as index sets
6847 
6848    Not Collective
6849 
6850    Input Parameter:
6851 .  A - matrix of type Elemental or ScaLAPACK
6852 
6853    Output Parameters:
6854 +  rows - rows in which this process owns elements
6855 -  cols - columns in which this process owns elements
6856 
6857    Level: intermediate
6858 
6859 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6860 @*/
6861 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6862 {
6863   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6864 
6865   PetscFunctionBegin;
6866   MatCheckPreallocated(A,1);
6867   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6868   if (f) {
6869     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6870   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6871     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6872     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6873   }
6874   PetscFunctionReturn(0);
6875 }
6876 
6877 /*@C
6878    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6879    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6880    to complete the factorization.
6881 
6882    Collective on Mat
6883 
6884    Input Parameters:
6885 +  mat - the matrix
6886 .  row - row permutation
6887 .  column - column permutation
6888 -  info - structure containing
6889 $      levels - number of levels of fill.
6890 $      expected fill - as ratio of original fill.
6891 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6892                 missing diagonal entries)
6893 
6894    Output Parameters:
6895 .  fact - new matrix that has been symbolically factored
6896 
6897    Notes:
6898     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6899 
6900    Most users should employ the simplified KSP interface for linear solvers
6901    instead of working directly with matrix algebra routines such as this.
6902    See, e.g., KSPCreate().
6903 
6904    Level: developer
6905 
6906 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6907           MatGetOrdering(), MatFactorInfo
6908 
6909     Note: this uses the definition of level of fill as in Y. Saad, 2003
6910 
6911     Developer Note: fortran interface is not autogenerated as the f90
6912     interface definition cannot be generated correctly [due to MatFactorInfo]
6913 
6914    References:
6915      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6916 @*/
6917 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6918 {
6919   PetscErrorCode ierr;
6920 
6921   PetscFunctionBegin;
6922   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
6923   PetscValidType(mat,2);
6924   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3);
6925   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4);
6926   PetscValidPointer(info,5);
6927   PetscValidPointer(fact,1);
6928   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6929   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6930   if (!fact->ops->ilufactorsymbolic) {
6931     MatSolverType stype;
6932     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6933     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype);
6934   }
6935   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6936   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6937   MatCheckPreallocated(mat,2);
6938 
6939   if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);}
6940   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6941   if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);}
6942   PetscFunctionReturn(0);
6943 }
6944 
6945 /*@C
6946    MatICCFactorSymbolic - Performs symbolic incomplete
6947    Cholesky factorization for a symmetric matrix.  Use
6948    MatCholeskyFactorNumeric() to complete the factorization.
6949 
6950    Collective on Mat
6951 
6952    Input Parameters:
6953 +  mat - the matrix
6954 .  perm - row and column permutation
6955 -  info - structure containing
6956 $      levels - number of levels of fill.
6957 $      expected fill - as ratio of original fill.
6958 
6959    Output Parameter:
6960 .  fact - the factored matrix
6961 
6962    Notes:
6963    Most users should employ the KSP interface for linear solvers
6964    instead of working directly with matrix algebra routines such as this.
6965    See, e.g., KSPCreate().
6966 
6967    Level: developer
6968 
6969 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6970 
6971     Note: this uses the definition of level of fill as in Y. Saad, 2003
6972 
6973     Developer Note: fortran interface is not autogenerated as the f90
6974     interface definition cannot be generated correctly [due to MatFactorInfo]
6975 
6976    References:
6977      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6978 @*/
6979 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6980 {
6981   PetscErrorCode ierr;
6982 
6983   PetscFunctionBegin;
6984   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
6985   PetscValidType(mat,2);
6986   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3);
6987   PetscValidPointer(info,4);
6988   PetscValidPointer(fact,1);
6989   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6990   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6991   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6992   if (!(fact)->ops->iccfactorsymbolic) {
6993     MatSolverType stype;
6994     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6995     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype);
6996   }
6997   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6998   MatCheckPreallocated(mat,2);
6999 
7000   if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);}
7001   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
7002   if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);}
7003   PetscFunctionReturn(0);
7004 }
7005 
7006 /*@C
7007    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
7008    points to an array of valid matrices, they may be reused to store the new
7009    submatrices.
7010 
7011    Collective on Mat
7012 
7013    Input Parameters:
7014 +  mat - the matrix
7015 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
7016 .  irow, icol - index sets of rows and columns to extract
7017 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7018 
7019    Output Parameter:
7020 .  submat - the array of submatrices
7021 
7022    Notes:
7023    MatCreateSubMatrices() can extract ONLY sequential submatrices
7024    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
7025    to extract a parallel submatrix.
7026 
7027    Some matrix types place restrictions on the row and column
7028    indices, such as that they be sorted or that they be equal to each other.
7029 
7030    The index sets may not have duplicate entries.
7031 
7032    When extracting submatrices from a parallel matrix, each processor can
7033    form a different submatrix by setting the rows and columns of its
7034    individual index sets according to the local submatrix desired.
7035 
7036    When finished using the submatrices, the user should destroy
7037    them with MatDestroySubMatrices().
7038 
7039    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7040    original matrix has not changed from that last call to MatCreateSubMatrices().
7041 
7042    This routine creates the matrices in submat; you should NOT create them before
7043    calling it. It also allocates the array of matrix pointers submat.
7044 
7045    For BAIJ matrices the index sets must respect the block structure, that is if they
7046    request one row/column in a block, they must request all rows/columns that are in
7047    that block. For example, if the block size is 2 you cannot request just row 0 and
7048    column 0.
7049 
7050    Fortran Note:
7051    The Fortran interface is slightly different from that given below; it
7052    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
7053 
7054    Level: advanced
7055 
7056 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7057 @*/
7058 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7059 {
7060   PetscErrorCode ierr;
7061   PetscInt       i;
7062   PetscBool      eq;
7063 
7064   PetscFunctionBegin;
7065   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7066   PetscValidType(mat,1);
7067   if (n) {
7068     PetscValidPointer(irow,3);
7069     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7070     PetscValidPointer(icol,4);
7071     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7072   }
7073   PetscValidPointer(submat,6);
7074   if (n && scall == MAT_REUSE_MATRIX) {
7075     PetscValidPointer(*submat,6);
7076     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7077   }
7078   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7079   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7080   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7081   MatCheckPreallocated(mat,1);
7082 
7083   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7084   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7085   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7086   for (i=0; i<n; i++) {
7087     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
7088     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7089     if (eq) {
7090       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7091     }
7092 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
7093     if (mat->boundtocpu && mat->bindingpropagates) {
7094       ierr = MatBindToCPU((*submat)[i],PETSC_TRUE);CHKERRQ(ierr);
7095       ierr = MatSetBindingPropagates((*submat)[i],PETSC_TRUE);CHKERRQ(ierr);
7096     }
7097 #endif
7098   }
7099   PetscFunctionReturn(0);
7100 }
7101 
7102 /*@C
7103    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
7104 
7105    Collective on Mat
7106 
7107    Input Parameters:
7108 +  mat - the matrix
7109 .  n   - the number of submatrixes to be extracted
7110 .  irow, icol - index sets of rows and columns to extract
7111 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7112 
7113    Output Parameter:
7114 .  submat - the array of submatrices
7115 
7116    Level: advanced
7117 
7118 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7119 @*/
7120 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7121 {
7122   PetscErrorCode ierr;
7123   PetscInt       i;
7124   PetscBool      eq;
7125 
7126   PetscFunctionBegin;
7127   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7128   PetscValidType(mat,1);
7129   if (n) {
7130     PetscValidPointer(irow,3);
7131     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7132     PetscValidPointer(icol,4);
7133     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7134   }
7135   PetscValidPointer(submat,6);
7136   if (n && scall == MAT_REUSE_MATRIX) {
7137     PetscValidPointer(*submat,6);
7138     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7139   }
7140   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7141   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7142   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7143   MatCheckPreallocated(mat,1);
7144 
7145   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7146   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7147   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7148   for (i=0; i<n; i++) {
7149     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7150     if (eq) {
7151       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7152     }
7153   }
7154   PetscFunctionReturn(0);
7155 }
7156 
7157 /*@C
7158    MatDestroyMatrices - Destroys an array of matrices.
7159 
7160    Collective on Mat
7161 
7162    Input Parameters:
7163 +  n - the number of local matrices
7164 -  mat - the matrices (note that this is a pointer to the array of matrices)
7165 
7166    Level: advanced
7167 
7168     Notes:
7169     Frees not only the matrices, but also the array that contains the matrices
7170            In Fortran will not free the array.
7171 
7172 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7173 @*/
7174 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7175 {
7176   PetscErrorCode ierr;
7177   PetscInt       i;
7178 
7179   PetscFunctionBegin;
7180   if (!*mat) PetscFunctionReturn(0);
7181   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7182   PetscValidPointer(mat,2);
7183 
7184   for (i=0; i<n; i++) {
7185     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7186   }
7187 
7188   /* memory is allocated even if n = 0 */
7189   ierr = PetscFree(*mat);CHKERRQ(ierr);
7190   PetscFunctionReturn(0);
7191 }
7192 
7193 /*@C
7194    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7195 
7196    Collective on Mat
7197 
7198    Input Parameters:
7199 +  n - the number of local matrices
7200 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7201                        sequence of MatCreateSubMatrices())
7202 
7203    Level: advanced
7204 
7205     Notes:
7206     Frees not only the matrices, but also the array that contains the matrices
7207            In Fortran will not free the array.
7208 
7209 .seealso: MatCreateSubMatrices()
7210 @*/
7211 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7212 {
7213   PetscErrorCode ierr;
7214   Mat            mat0;
7215 
7216   PetscFunctionBegin;
7217   if (!*mat) PetscFunctionReturn(0);
7218   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7219   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7220   PetscValidPointer(mat,2);
7221 
7222   mat0 = (*mat)[0];
7223   if (mat0 && mat0->ops->destroysubmatrices) {
7224     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7225   } else {
7226     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7227   }
7228   PetscFunctionReturn(0);
7229 }
7230 
7231 /*@C
7232    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7233 
7234    Collective on Mat
7235 
7236    Input Parameters:
7237 .  mat - the matrix
7238 
7239    Output Parameter:
7240 .  matstruct - the sequential matrix with the nonzero structure of mat
7241 
7242   Level: intermediate
7243 
7244 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7245 @*/
7246 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7247 {
7248   PetscErrorCode ierr;
7249 
7250   PetscFunctionBegin;
7251   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7252   PetscValidPointer(matstruct,2);
7253 
7254   PetscValidType(mat,1);
7255   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7256   MatCheckPreallocated(mat,1);
7257 
7258   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7259   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7260   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7261   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7262   PetscFunctionReturn(0);
7263 }
7264 
7265 /*@C
7266    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7267 
7268    Collective on Mat
7269 
7270    Input Parameters:
7271 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7272                        sequence of MatGetSequentialNonzeroStructure())
7273 
7274    Level: advanced
7275 
7276     Notes:
7277     Frees not only the matrices, but also the array that contains the matrices
7278 
7279 .seealso: MatGetSeqNonzeroStructure()
7280 @*/
7281 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7282 {
7283   PetscErrorCode ierr;
7284 
7285   PetscFunctionBegin;
7286   PetscValidPointer(mat,1);
7287   ierr = MatDestroy(mat);CHKERRQ(ierr);
7288   PetscFunctionReturn(0);
7289 }
7290 
7291 /*@
7292    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7293    replaces the index sets by larger ones that represent submatrices with
7294    additional overlap.
7295 
7296    Collective on Mat
7297 
7298    Input Parameters:
7299 +  mat - the matrix
7300 .  n   - the number of index sets
7301 .  is  - the array of index sets (these index sets will changed during the call)
7302 -  ov  - the additional overlap requested
7303 
7304    Options Database:
7305 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7306 
7307    Level: developer
7308 
7309 .seealso: MatCreateSubMatrices()
7310 @*/
7311 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7312 {
7313   PetscErrorCode ierr;
7314 
7315   PetscFunctionBegin;
7316   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7317   PetscValidType(mat,1);
7318   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7319   if (n) {
7320     PetscValidPointer(is,3);
7321     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7322   }
7323   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7324   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7325   MatCheckPreallocated(mat,1);
7326 
7327   if (!ov) PetscFunctionReturn(0);
7328   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7329   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7330   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7331   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7332   PetscFunctionReturn(0);
7333 }
7334 
7335 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7336 
7337 /*@
7338    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7339    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7340    additional overlap.
7341 
7342    Collective on Mat
7343 
7344    Input Parameters:
7345 +  mat - the matrix
7346 .  n   - the number of index sets
7347 .  is  - the array of index sets (these index sets will changed during the call)
7348 -  ov  - the additional overlap requested
7349 
7350    Options Database:
7351 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7352 
7353    Level: developer
7354 
7355 .seealso: MatCreateSubMatrices()
7356 @*/
7357 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7358 {
7359   PetscInt       i;
7360   PetscErrorCode ierr;
7361 
7362   PetscFunctionBegin;
7363   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7364   PetscValidType(mat,1);
7365   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7366   if (n) {
7367     PetscValidPointer(is,3);
7368     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7369   }
7370   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7371   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7372   MatCheckPreallocated(mat,1);
7373   if (!ov) PetscFunctionReturn(0);
7374   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7375   for (i=0; i<n; i++) {
7376         ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7377   }
7378   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7379   PetscFunctionReturn(0);
7380 }
7381 
7382 /*@
7383    MatGetBlockSize - Returns the matrix block size.
7384 
7385    Not Collective
7386 
7387    Input Parameter:
7388 .  mat - the matrix
7389 
7390    Output Parameter:
7391 .  bs - block size
7392 
7393    Notes:
7394     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7395 
7396    If the block size has not been set yet this routine returns 1.
7397 
7398    Level: intermediate
7399 
7400 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7401 @*/
7402 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7403 {
7404   PetscFunctionBegin;
7405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7406   PetscValidIntPointer(bs,2);
7407   *bs = PetscAbs(mat->rmap->bs);
7408   PetscFunctionReturn(0);
7409 }
7410 
7411 /*@
7412    MatGetBlockSizes - Returns the matrix block row and column sizes.
7413 
7414    Not Collective
7415 
7416    Input Parameter:
7417 .  mat - the matrix
7418 
7419    Output Parameters:
7420 +  rbs - row block size
7421 -  cbs - column block size
7422 
7423    Notes:
7424     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7425     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7426 
7427    If a block size has not been set yet this routine returns 1.
7428 
7429    Level: intermediate
7430 
7431 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7432 @*/
7433 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7434 {
7435   PetscFunctionBegin;
7436   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7437   if (rbs) PetscValidIntPointer(rbs,2);
7438   if (cbs) PetscValidIntPointer(cbs,3);
7439   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7440   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7441   PetscFunctionReturn(0);
7442 }
7443 
7444 /*@
7445    MatSetBlockSize - Sets the matrix block size.
7446 
7447    Logically Collective on Mat
7448 
7449    Input Parameters:
7450 +  mat - the matrix
7451 -  bs - block size
7452 
7453    Notes:
7454     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7455     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7456 
7457     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7458     is compatible with the matrix local sizes.
7459 
7460    Level: intermediate
7461 
7462 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7463 @*/
7464 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7465 {
7466   PetscErrorCode ierr;
7467 
7468   PetscFunctionBegin;
7469   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7470   PetscValidLogicalCollectiveInt(mat,bs,2);
7471   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7472   PetscFunctionReturn(0);
7473 }
7474 
7475 /*@
7476    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7477 
7478    Logically Collective on Mat
7479 
7480    Input Parameters:
7481 +  mat - the matrix
7482 .  nblocks - the number of blocks on this process
7483 -  bsizes - the block sizes
7484 
7485    Notes:
7486     Currently used by PCVPBJACOBI for SeqAIJ matrices
7487 
7488    Level: intermediate
7489 
7490 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
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 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
9226       if (mat->boundtocpu && mat->bindingpropagates) {
9227         ierr = VecSetBindingPropagates(*right,PETSC_TRUE);CHKERRQ(ierr);
9228         ierr = VecBindToCPU(*right,PETSC_TRUE);CHKERRQ(ierr);
9229       }
9230 #endif
9231       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9232     }
9233     if (left) {
9234       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9235       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9236       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9237       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9238       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9239 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
9240       if (mat->boundtocpu && mat->bindingpropagates) {
9241         ierr = VecSetBindingPropagates(*left,PETSC_TRUE);CHKERRQ(ierr);
9242         ierr = VecBindToCPU(*left,PETSC_TRUE);CHKERRQ(ierr);
9243       }
9244 #endif
9245       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9246     }
9247   }
9248   PetscFunctionReturn(0);
9249 }
9250 
9251 /*@C
9252    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9253      with default values.
9254 
9255    Not Collective
9256 
9257    Input Parameters:
9258 .    info - the MatFactorInfo data structure
9259 
9260    Notes:
9261     The solvers are generally used through the KSP and PC objects, for example
9262           PCLU, PCILU, PCCHOLESKY, PCICC
9263 
9264    Level: developer
9265 
9266 .seealso: MatFactorInfo
9267 
9268     Developer Note: fortran interface is not autogenerated as the f90
9269     interface definition cannot be generated correctly [due to MatFactorInfo]
9270 
9271 @*/
9272 
9273 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9274 {
9275   PetscErrorCode ierr;
9276 
9277   PetscFunctionBegin;
9278   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9279   PetscFunctionReturn(0);
9280 }
9281 
9282 /*@
9283    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9284 
9285    Collective on Mat
9286 
9287    Input Parameters:
9288 +  mat - the factored matrix
9289 -  is - the index set defining the Schur indices (0-based)
9290 
9291    Notes:
9292     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9293 
9294    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9295 
9296    Level: developer
9297 
9298 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9299           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9300 
9301 @*/
9302 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9303 {
9304   PetscErrorCode ierr,(*f)(Mat,IS);
9305 
9306   PetscFunctionBegin;
9307   PetscValidType(mat,1);
9308   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9309   PetscValidType(is,2);
9310   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9311   PetscCheckSameComm(mat,1,is,2);
9312   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9313   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9314   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");
9315   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9316   ierr = (*f)(mat,is);CHKERRQ(ierr);
9317   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9318   PetscFunctionReturn(0);
9319 }
9320 
9321 /*@
9322   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9323 
9324    Logically Collective on Mat
9325 
9326    Input Parameters:
9327 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9328 .  S - location where to return the Schur complement, can be NULL
9329 -  status - the status of the Schur complement matrix, can be NULL
9330 
9331    Notes:
9332    You must call MatFactorSetSchurIS() before calling this routine.
9333 
9334    The routine provides a copy of the Schur matrix stored within the solver data structures.
9335    The caller must destroy the object when it is no longer needed.
9336    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9337 
9338    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)
9339 
9340    Developer Notes:
9341     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9342    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9343 
9344    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9345 
9346    Level: advanced
9347 
9348    References:
9349 
9350 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9351 @*/
9352 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9353 {
9354   PetscErrorCode ierr;
9355 
9356   PetscFunctionBegin;
9357   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9358   if (S) PetscValidPointer(S,2);
9359   if (status) PetscValidPointer(status,3);
9360   if (S) {
9361     PetscErrorCode (*f)(Mat,Mat*);
9362 
9363     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9364     if (f) {
9365       ierr = (*f)(F,S);CHKERRQ(ierr);
9366     } else {
9367       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9368     }
9369   }
9370   if (status) *status = F->schur_status;
9371   PetscFunctionReturn(0);
9372 }
9373 
9374 /*@
9375   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9376 
9377    Logically Collective on Mat
9378 
9379    Input Parameters:
9380 +  F - the factored matrix obtained by calling MatGetFactor()
9381 .  *S - location where to return the Schur complement, can be NULL
9382 -  status - the status of the Schur complement matrix, can be NULL
9383 
9384    Notes:
9385    You must call MatFactorSetSchurIS() before calling this routine.
9386 
9387    Schur complement mode is currently implemented for sequential matrices.
9388    The routine returns a the Schur Complement stored within the data strutures of the solver.
9389    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9390    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9391 
9392    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9393 
9394    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9395 
9396    Level: advanced
9397 
9398    References:
9399 
9400 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9401 @*/
9402 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9403 {
9404   PetscFunctionBegin;
9405   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9406   if (S) PetscValidPointer(S,2);
9407   if (status) PetscValidPointer(status,3);
9408   if (S) *S = F->schur;
9409   if (status) *status = F->schur_status;
9410   PetscFunctionReturn(0);
9411 }
9412 
9413 /*@
9414   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9415 
9416    Logically Collective on Mat
9417 
9418    Input Parameters:
9419 +  F - the factored matrix obtained by calling MatGetFactor()
9420 .  *S - location where the Schur complement is stored
9421 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9422 
9423    Notes:
9424 
9425    Level: advanced
9426 
9427    References:
9428 
9429 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9430 @*/
9431 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9432 {
9433   PetscErrorCode ierr;
9434 
9435   PetscFunctionBegin;
9436   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9437   if (S) {
9438     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9439     *S = NULL;
9440   }
9441   F->schur_status = status;
9442   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9443   PetscFunctionReturn(0);
9444 }
9445 
9446 /*@
9447   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9448 
9449    Logically Collective on Mat
9450 
9451    Input Parameters:
9452 +  F - the factored matrix obtained by calling MatGetFactor()
9453 .  rhs - location where the right hand side of the Schur complement system is stored
9454 -  sol - location where the solution of the Schur complement system has to be returned
9455 
9456    Notes:
9457    The sizes of the vectors should match the size of the Schur complement
9458 
9459    Must be called after MatFactorSetSchurIS()
9460 
9461    Level: advanced
9462 
9463    References:
9464 
9465 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9466 @*/
9467 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9468 {
9469   PetscErrorCode ierr;
9470 
9471   PetscFunctionBegin;
9472   PetscValidType(F,1);
9473   PetscValidType(rhs,2);
9474   PetscValidType(sol,3);
9475   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9476   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9477   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9478   PetscCheckSameComm(F,1,rhs,2);
9479   PetscCheckSameComm(F,1,sol,3);
9480   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9481   switch (F->schur_status) {
9482   case MAT_FACTOR_SCHUR_FACTORED:
9483     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9484     break;
9485   case MAT_FACTOR_SCHUR_INVERTED:
9486     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9487     break;
9488   default:
9489     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9490   }
9491   PetscFunctionReturn(0);
9492 }
9493 
9494 /*@
9495   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9496 
9497    Logically Collective on Mat
9498 
9499    Input Parameters:
9500 +  F - the factored matrix obtained by calling MatGetFactor()
9501 .  rhs - location where the right hand side of the Schur complement system is stored
9502 -  sol - location where the solution of the Schur complement system has to be returned
9503 
9504    Notes:
9505    The sizes of the vectors should match the size of the Schur complement
9506 
9507    Must be called after MatFactorSetSchurIS()
9508 
9509    Level: advanced
9510 
9511    References:
9512 
9513 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9514 @*/
9515 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9516 {
9517   PetscErrorCode ierr;
9518 
9519   PetscFunctionBegin;
9520   PetscValidType(F,1);
9521   PetscValidType(rhs,2);
9522   PetscValidType(sol,3);
9523   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9524   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9525   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9526   PetscCheckSameComm(F,1,rhs,2);
9527   PetscCheckSameComm(F,1,sol,3);
9528   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9529   switch (F->schur_status) {
9530   case MAT_FACTOR_SCHUR_FACTORED:
9531     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9532     break;
9533   case MAT_FACTOR_SCHUR_INVERTED:
9534     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9535     break;
9536   default:
9537     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9538   }
9539   PetscFunctionReturn(0);
9540 }
9541 
9542 /*@
9543   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9544 
9545    Logically Collective on Mat
9546 
9547    Input Parameters:
9548 .  F - the factored matrix obtained by calling MatGetFactor()
9549 
9550    Notes:
9551     Must be called after MatFactorSetSchurIS().
9552 
9553    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9554 
9555    Level: advanced
9556 
9557    References:
9558 
9559 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9560 @*/
9561 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9562 {
9563   PetscErrorCode ierr;
9564 
9565   PetscFunctionBegin;
9566   PetscValidType(F,1);
9567   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9568   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9569   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9570   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9571   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9572   PetscFunctionReturn(0);
9573 }
9574 
9575 /*@
9576   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9577 
9578    Logically Collective on Mat
9579 
9580    Input Parameters:
9581 .  F - the factored matrix obtained by calling MatGetFactor()
9582 
9583    Notes:
9584     Must be called after MatFactorSetSchurIS().
9585 
9586    Level: advanced
9587 
9588    References:
9589 
9590 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9591 @*/
9592 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9593 {
9594   PetscErrorCode ierr;
9595 
9596   PetscFunctionBegin;
9597   PetscValidType(F,1);
9598   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9599   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9600   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9601   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9602   PetscFunctionReturn(0);
9603 }
9604 
9605 /*@
9606    MatPtAP - Creates the matrix product C = P^T * A * P
9607 
9608    Neighbor-wise Collective on Mat
9609 
9610    Input Parameters:
9611 +  A - the matrix
9612 .  P - the projection matrix
9613 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9614 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9615           if the result is a dense matrix this is irrelevant
9616 
9617    Output Parameters:
9618 .  C - the product matrix
9619 
9620    Notes:
9621    C will be created and must be destroyed by the user with MatDestroy().
9622 
9623    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9624 
9625    Level: intermediate
9626 
9627 .seealso: MatMatMult(), MatRARt()
9628 @*/
9629 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9630 {
9631   PetscErrorCode ierr;
9632 
9633   PetscFunctionBegin;
9634   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9635   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9636 
9637   if (scall == MAT_INITIAL_MATRIX) {
9638     ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr);
9639     ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr);
9640     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9641     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9642 
9643     (*C)->product->api_user = PETSC_TRUE;
9644     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9645     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);
9646     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9647   } else { /* scall == MAT_REUSE_MATRIX */
9648     ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr);
9649   }
9650 
9651   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9652   if (A->symmetric_set && A->symmetric) {
9653     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9654   }
9655   PetscFunctionReturn(0);
9656 }
9657 
9658 /*@
9659    MatRARt - Creates the matrix product C = R * A * R^T
9660 
9661    Neighbor-wise Collective on Mat
9662 
9663    Input Parameters:
9664 +  A - the matrix
9665 .  R - the projection matrix
9666 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9667 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9668           if the result is a dense matrix this is irrelevant
9669 
9670    Output Parameters:
9671 .  C - the product matrix
9672 
9673    Notes:
9674    C will be created and must be destroyed by the user with MatDestroy().
9675 
9676    This routine is currently only implemented for pairs of AIJ matrices and classes
9677    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9678    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9679    We recommend using MatPtAP().
9680 
9681    Level: intermediate
9682 
9683 .seealso: MatMatMult(), MatPtAP()
9684 @*/
9685 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9686 {
9687   PetscErrorCode ierr;
9688 
9689   PetscFunctionBegin;
9690   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9691   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9692 
9693   if (scall == MAT_INITIAL_MATRIX) {
9694     ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr);
9695     ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr);
9696     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9697     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9698 
9699     (*C)->product->api_user = PETSC_TRUE;
9700     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9701     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);
9702     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9703   } else { /* scall == MAT_REUSE_MATRIX */
9704     ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr);
9705   }
9706 
9707   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9708   if (A->symmetric_set && A->symmetric) {
9709     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9710   }
9711   PetscFunctionReturn(0);
9712 }
9713 
9714 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9715 {
9716   PetscErrorCode ierr;
9717 
9718   PetscFunctionBegin;
9719   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9720 
9721   if (scall == MAT_INITIAL_MATRIX) {
9722     ierr = PetscInfo1(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr);
9723     ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr);
9724     ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9725     ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
9726     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9727 
9728     (*C)->product->api_user = PETSC_TRUE;
9729     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9730     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9731   } else { /* scall == MAT_REUSE_MATRIX */
9732     Mat_Product *product = (*C)->product;
9733     PetscBool isdense;
9734 
9735     ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9736     if (isdense && product && product->type != ptype) {
9737       ierr = MatProductClear(*C);CHKERRQ(ierr);
9738       product = NULL;
9739     }
9740     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);
9741     if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */
9742       if (isdense) {
9743         ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr);
9744         product = (*C)->product;
9745         product->fill     = fill;
9746         product->api_user = PETSC_TRUE;
9747         product->clear    = PETSC_TRUE;
9748 
9749         ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9750         ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9751         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);
9752         ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9753       } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first");
9754     } else { /* user may change input matrices A or B when REUSE */
9755       ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr);
9756     }
9757   }
9758   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9759   PetscFunctionReturn(0);
9760 }
9761 
9762 /*@
9763    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9764 
9765    Neighbor-wise Collective on Mat
9766 
9767    Input Parameters:
9768 +  A - the left matrix
9769 .  B - the right matrix
9770 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9771 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9772           if the result is a dense matrix this is irrelevant
9773 
9774    Output Parameters:
9775 .  C - the product matrix
9776 
9777    Notes:
9778    Unless scall is MAT_REUSE_MATRIX C will be created.
9779 
9780    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
9781    call to this function with MAT_INITIAL_MATRIX.
9782 
9783    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9784 
9785    If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly.
9786 
9787    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.
9788 
9789    Example of Usage:
9790 .vb
9791      MatProductCreate(A,B,NULL,&C);
9792      MatProductSetType(C,MATPRODUCT_AB);
9793      MatProductSymbolic(C);
9794      MatProductNumeric(C); // compute C=A * B
9795      MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1
9796      MatProductNumeric(C);
9797      MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1
9798      MatProductNumeric(C);
9799 .ve
9800 
9801    Level: intermediate
9802 
9803 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP(), MatProductCreate(), MatProductSymbolic(), MatProductReplaceMats(), MatProductNumeric()
9804 @*/
9805 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9806 {
9807   PetscErrorCode ierr;
9808 
9809   PetscFunctionBegin;
9810   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr);
9811   PetscFunctionReturn(0);
9812 }
9813 
9814 /*@
9815    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9816 
9817    Neighbor-wise Collective on Mat
9818 
9819    Input Parameters:
9820 +  A - the left matrix
9821 .  B - the right matrix
9822 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9823 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9824 
9825    Output Parameters:
9826 .  C - the product matrix
9827 
9828    Notes:
9829    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9830 
9831    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9832 
9833   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9834    actually needed.
9835 
9836    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9837    and for pairs of MPIDense matrices.
9838 
9839    Options Database Keys:
9840 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9841                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9842                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9843 
9844    Level: intermediate
9845 
9846 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP()
9847 @*/
9848 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9849 {
9850   PetscErrorCode ierr;
9851 
9852   PetscFunctionBegin;
9853   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr);
9854   PetscFunctionReturn(0);
9855 }
9856 
9857 /*@
9858    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9859 
9860    Neighbor-wise Collective on Mat
9861 
9862    Input Parameters:
9863 +  A - the left matrix
9864 .  B - the right matrix
9865 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9866 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9867 
9868    Output Parameters:
9869 .  C - the product matrix
9870 
9871    Notes:
9872    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9873 
9874    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9875 
9876   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9877    actually needed.
9878 
9879    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9880    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9881 
9882    Level: intermediate
9883 
9884 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9885 @*/
9886 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9887 {
9888   PetscErrorCode ierr;
9889 
9890   PetscFunctionBegin;
9891   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr);
9892   PetscFunctionReturn(0);
9893 }
9894 
9895 /*@
9896    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9897 
9898    Neighbor-wise Collective on Mat
9899 
9900    Input Parameters:
9901 +  A - the left matrix
9902 .  B - the middle matrix
9903 .  C - the right matrix
9904 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9905 -  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
9906           if the result is a dense matrix this is irrelevant
9907 
9908    Output Parameters:
9909 .  D - the product matrix
9910 
9911    Notes:
9912    Unless scall is MAT_REUSE_MATRIX D will be created.
9913 
9914    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9915 
9916    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9917    actually needed.
9918 
9919    If you have many matrices with the same non-zero structure to multiply, you
9920    should use MAT_REUSE_MATRIX in all calls but the first or
9921 
9922    Level: intermediate
9923 
9924 .seealso: MatMatMult, MatPtAP()
9925 @*/
9926 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9927 {
9928   PetscErrorCode ierr;
9929 
9930   PetscFunctionBegin;
9931   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6);
9932   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9933 
9934   if (scall == MAT_INITIAL_MATRIX) {
9935     ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr);
9936     ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr);
9937     ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr);
9938     ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr);
9939 
9940     (*D)->product->api_user = PETSC_TRUE;
9941     ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr);
9942     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);
9943     ierr = MatProductSymbolic(*D);CHKERRQ(ierr);
9944   } else { /* user may change input matrices when REUSE */
9945     ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr);
9946   }
9947   ierr = MatProductNumeric(*D);CHKERRQ(ierr);
9948   PetscFunctionReturn(0);
9949 }
9950 
9951 /*@
9952    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9953 
9954    Collective on Mat
9955 
9956    Input Parameters:
9957 +  mat - the matrix
9958 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9959 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9960 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9961 
9962    Output Parameter:
9963 .  matredundant - redundant matrix
9964 
9965    Notes:
9966    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9967    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9968 
9969    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9970    calling it.
9971 
9972    Level: advanced
9973 
9974 .seealso: MatDestroy()
9975 @*/
9976 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9977 {
9978   PetscErrorCode ierr;
9979   MPI_Comm       comm;
9980   PetscMPIInt    size;
9981   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9982   Mat_Redundant  *redund=NULL;
9983   PetscSubcomm   psubcomm=NULL;
9984   MPI_Comm       subcomm_in=subcomm;
9985   Mat            *matseq;
9986   IS             isrow,iscol;
9987   PetscBool      newsubcomm=PETSC_FALSE;
9988 
9989   PetscFunctionBegin;
9990   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9991   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9992     PetscValidPointer(*matredundant,5);
9993     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9994   }
9995 
9996   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
9997   if (size == 1 || nsubcomm == 1) {
9998     if (reuse == MAT_INITIAL_MATRIX) {
9999       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10000     } else {
10001       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");
10002       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10003     }
10004     PetscFunctionReturn(0);
10005   }
10006 
10007   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10008   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10009   MatCheckPreallocated(mat,1);
10010 
10011   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10012   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10013     /* create psubcomm, then get subcomm */
10014     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10015     ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10016     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10017 
10018     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10019     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10020     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10021     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10022     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10023     newsubcomm = PETSC_TRUE;
10024     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10025   }
10026 
10027   /* get isrow, iscol and a local sequential matrix matseq[0] */
10028   if (reuse == MAT_INITIAL_MATRIX) {
10029     mloc_sub = PETSC_DECIDE;
10030     nloc_sub = PETSC_DECIDE;
10031     if (bs < 1) {
10032       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10033       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10034     } else {
10035       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10036       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10037     }
10038     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRMPI(ierr);
10039     rstart = rend - mloc_sub;
10040     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10041     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10042   } else { /* reuse == MAT_REUSE_MATRIX */
10043     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");
10044     /* retrieve subcomm */
10045     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10046     redund = (*matredundant)->redundant;
10047     isrow  = redund->isrow;
10048     iscol  = redund->iscol;
10049     matseq = redund->matseq;
10050   }
10051   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10052 
10053   /* get matredundant over subcomm */
10054   if (reuse == MAT_INITIAL_MATRIX) {
10055     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10056 
10057     /* create a supporting struct and attach it to C for reuse */
10058     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10059     (*matredundant)->redundant = redund;
10060     redund->isrow              = isrow;
10061     redund->iscol              = iscol;
10062     redund->matseq             = matseq;
10063     if (newsubcomm) {
10064       redund->subcomm          = subcomm;
10065     } else {
10066       redund->subcomm          = MPI_COMM_NULL;
10067     }
10068   } else {
10069     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10070   }
10071 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
10072   if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) {
10073     ierr = MatBindToCPU(*matredundant,PETSC_TRUE);CHKERRQ(ierr);
10074     ierr = MatSetBindingPropagates(*matredundant,PETSC_TRUE);CHKERRQ(ierr);
10075   }
10076 #endif
10077   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10078   PetscFunctionReturn(0);
10079 }
10080 
10081 /*@C
10082    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10083    a given 'mat' object. Each submatrix can span multiple procs.
10084 
10085    Collective on Mat
10086 
10087    Input Parameters:
10088 +  mat - the matrix
10089 .  subcomm - the subcommunicator obtained by com_split(comm)
10090 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10091 
10092    Output Parameter:
10093 .  subMat - 'parallel submatrices each spans a given subcomm
10094 
10095   Notes:
10096   The submatrix partition across processors is dictated by 'subComm' a
10097   communicator obtained by com_split(comm). The comm_split
10098   is not restriced to be grouped with consecutive original ranks.
10099 
10100   Due the comm_split() usage, the parallel layout of the submatrices
10101   map directly to the layout of the original matrix [wrt the local
10102   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10103   into the 'DiagonalMat' of the subMat, hence it is used directly from
10104   the subMat. However the offDiagMat looses some columns - and this is
10105   reconstructed with MatSetValues()
10106 
10107   Level: advanced
10108 
10109 .seealso: MatCreateSubMatrices()
10110 @*/
10111 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10112 {
10113   PetscErrorCode ierr;
10114   PetscMPIInt    commsize,subCommSize;
10115 
10116   PetscFunctionBegin;
10117   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRMPI(ierr);
10118   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRMPI(ierr);
10119   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10120 
10121   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");
10122   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10123   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10124   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10125   PetscFunctionReturn(0);
10126 }
10127 
10128 /*@
10129    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10130 
10131    Not Collective
10132 
10133    Input Parameters:
10134 +  mat - matrix to extract local submatrix from
10135 .  isrow - local row indices for submatrix
10136 -  iscol - local column indices for submatrix
10137 
10138    Output Parameter:
10139 .  submat - the submatrix
10140 
10141    Level: intermediate
10142 
10143    Notes:
10144    The submat should be returned with MatRestoreLocalSubMatrix().
10145 
10146    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10147    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10148 
10149    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10150    MatSetValuesBlockedLocal() will also be implemented.
10151 
10152    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10153    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10154 
10155 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10156 @*/
10157 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10158 {
10159   PetscErrorCode ierr;
10160 
10161   PetscFunctionBegin;
10162   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10163   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10164   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10165   PetscCheckSameComm(isrow,2,iscol,3);
10166   PetscValidPointer(submat,4);
10167   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10168 
10169   if (mat->ops->getlocalsubmatrix) {
10170     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10171   } else {
10172     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10173   }
10174   PetscFunctionReturn(0);
10175 }
10176 
10177 /*@
10178    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10179 
10180    Not Collective
10181 
10182    Input Parameters:
10183 +  mat - matrix to extract local submatrix from
10184 .  isrow - local row indices for submatrix
10185 .  iscol - local column indices for submatrix
10186 -  submat - the submatrix
10187 
10188    Level: intermediate
10189 
10190 .seealso: MatGetLocalSubMatrix()
10191 @*/
10192 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10193 {
10194   PetscErrorCode ierr;
10195 
10196   PetscFunctionBegin;
10197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10198   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10199   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10200   PetscCheckSameComm(isrow,2,iscol,3);
10201   PetscValidPointer(submat,4);
10202   if (*submat) {
10203     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10204   }
10205 
10206   if (mat->ops->restorelocalsubmatrix) {
10207     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10208   } else {
10209     ierr = MatDestroy(submat);CHKERRQ(ierr);
10210   }
10211   *submat = NULL;
10212   PetscFunctionReturn(0);
10213 }
10214 
10215 /* --------------------------------------------------------*/
10216 /*@
10217    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10218 
10219    Collective on Mat
10220 
10221    Input Parameter:
10222 .  mat - the matrix
10223 
10224    Output Parameter:
10225 .  is - if any rows have zero diagonals this contains the list of them
10226 
10227    Level: developer
10228 
10229 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10230 @*/
10231 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10232 {
10233   PetscErrorCode ierr;
10234 
10235   PetscFunctionBegin;
10236   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10237   PetscValidType(mat,1);
10238   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10239   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10240 
10241   if (!mat->ops->findzerodiagonals) {
10242     Vec                diag;
10243     const PetscScalar *a;
10244     PetscInt          *rows;
10245     PetscInt           rStart, rEnd, r, nrow = 0;
10246 
10247     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10248     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10249     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10250     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10251     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10252     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10253     nrow = 0;
10254     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10255     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10256     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10257     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10258   } else {
10259     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10260   }
10261   PetscFunctionReturn(0);
10262 }
10263 
10264 /*@
10265    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10266 
10267    Collective on Mat
10268 
10269    Input Parameter:
10270 .  mat - the matrix
10271 
10272    Output Parameter:
10273 .  is - contains the list of rows with off block diagonal entries
10274 
10275    Level: developer
10276 
10277 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10278 @*/
10279 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10280 {
10281   PetscErrorCode ierr;
10282 
10283   PetscFunctionBegin;
10284   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10285   PetscValidType(mat,1);
10286   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10287   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10288 
10289   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);
10290   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10291   PetscFunctionReturn(0);
10292 }
10293 
10294 /*@C
10295   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10296 
10297   Collective on Mat
10298 
10299   Input Parameters:
10300 . mat - the matrix
10301 
10302   Output Parameters:
10303 . values - the block inverses in column major order (FORTRAN-like)
10304 
10305    Note:
10306    This routine is not available from Fortran.
10307 
10308   Level: advanced
10309 
10310 .seealso: MatInvertBockDiagonalMat
10311 @*/
10312 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10313 {
10314   PetscErrorCode ierr;
10315 
10316   PetscFunctionBegin;
10317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10318   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10319   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10320   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10321   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10322   PetscFunctionReturn(0);
10323 }
10324 
10325 /*@C
10326   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10327 
10328   Collective on Mat
10329 
10330   Input Parameters:
10331 + mat - the matrix
10332 . nblocks - the number of blocks
10333 - bsizes - the size of each block
10334 
10335   Output Parameters:
10336 . values - the block inverses in column major order (FORTRAN-like)
10337 
10338    Note:
10339    This routine is not available from Fortran.
10340 
10341   Level: advanced
10342 
10343 .seealso: MatInvertBockDiagonal()
10344 @*/
10345 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10346 {
10347   PetscErrorCode ierr;
10348 
10349   PetscFunctionBegin;
10350   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10351   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10352   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10353   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
10354   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10355   PetscFunctionReturn(0);
10356 }
10357 
10358 /*@
10359   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10360 
10361   Collective on Mat
10362 
10363   Input Parameters:
10364 . A - the matrix
10365 
10366   Output Parameters:
10367 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10368 
10369   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10370 
10371   Level: advanced
10372 
10373 .seealso: MatInvertBockDiagonal()
10374 @*/
10375 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10376 {
10377   PetscErrorCode     ierr;
10378   const PetscScalar *vals;
10379   PetscInt          *dnnz;
10380   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10381 
10382   PetscFunctionBegin;
10383   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10384   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10385   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10386   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10387   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10388   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10389   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10390   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10391   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10392   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10393   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10394   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10395   for (i = rstart/bs; i < rend/bs; i++) {
10396     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10397   }
10398   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10399   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10400   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10401   PetscFunctionReturn(0);
10402 }
10403 
10404 /*@C
10405     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10406     via MatTransposeColoringCreate().
10407 
10408     Collective on MatTransposeColoring
10409 
10410     Input Parameter:
10411 .   c - coloring context
10412 
10413     Level: intermediate
10414 
10415 .seealso: MatTransposeColoringCreate()
10416 @*/
10417 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10418 {
10419   PetscErrorCode       ierr;
10420   MatTransposeColoring matcolor=*c;
10421 
10422   PetscFunctionBegin;
10423   if (!matcolor) PetscFunctionReturn(0);
10424   if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);}
10425 
10426   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10427   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10428   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10429   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10430   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10431   if (matcolor->brows>0) {
10432     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10433   }
10434   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10435   PetscFunctionReturn(0);
10436 }
10437 
10438 /*@C
10439     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10440     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10441     MatTransposeColoring to sparse B.
10442 
10443     Collective on MatTransposeColoring
10444 
10445     Input Parameters:
10446 +   B - sparse matrix B
10447 .   Btdense - symbolic dense matrix B^T
10448 -   coloring - coloring context created with MatTransposeColoringCreate()
10449 
10450     Output Parameter:
10451 .   Btdense - dense matrix B^T
10452 
10453     Level: advanced
10454 
10455      Notes:
10456     These are used internally for some implementations of MatRARt()
10457 
10458 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10459 
10460 @*/
10461 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10462 {
10463   PetscErrorCode ierr;
10464 
10465   PetscFunctionBegin;
10466   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10467   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3);
10468   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10469 
10470   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10471   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10472   PetscFunctionReturn(0);
10473 }
10474 
10475 /*@C
10476     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10477     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10478     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10479     Csp from Cden.
10480 
10481     Collective on MatTransposeColoring
10482 
10483     Input Parameters:
10484 +   coloring - coloring context created with MatTransposeColoringCreate()
10485 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10486 
10487     Output Parameter:
10488 .   Csp - sparse matrix
10489 
10490     Level: advanced
10491 
10492      Notes:
10493     These are used internally for some implementations of MatRARt()
10494 
10495 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10496 
10497 @*/
10498 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10499 {
10500   PetscErrorCode ierr;
10501 
10502   PetscFunctionBegin;
10503   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10504   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10505   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10506 
10507   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10508   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10509   ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10510   ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10511   PetscFunctionReturn(0);
10512 }
10513 
10514 /*@C
10515    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10516 
10517    Collective on Mat
10518 
10519    Input Parameters:
10520 +  mat - the matrix product C
10521 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10522 
10523     Output Parameter:
10524 .   color - the new coloring context
10525 
10526     Level: intermediate
10527 
10528 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10529            MatTransColoringApplyDenToSp()
10530 @*/
10531 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10532 {
10533   MatTransposeColoring c;
10534   MPI_Comm             comm;
10535   PetscErrorCode       ierr;
10536 
10537   PetscFunctionBegin;
10538   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10539   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10540   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10541 
10542   c->ctype = iscoloring->ctype;
10543   if (mat->ops->transposecoloringcreate) {
10544     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10545   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10546 
10547   *color = c;
10548   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10549   PetscFunctionReturn(0);
10550 }
10551 
10552 /*@
10553       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10554         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10555         same, otherwise it will be larger
10556 
10557      Not Collective
10558 
10559   Input Parameter:
10560 .    A  - the matrix
10561 
10562   Output Parameter:
10563 .    state - the current state
10564 
10565   Notes:
10566     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10567          different matrices
10568 
10569   Level: intermediate
10570 
10571 @*/
10572 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10573 {
10574   PetscFunctionBegin;
10575   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10576   *state = mat->nonzerostate;
10577   PetscFunctionReturn(0);
10578 }
10579 
10580 /*@
10581       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10582                  matrices from each processor
10583 
10584     Collective
10585 
10586    Input Parameters:
10587 +    comm - the communicators the parallel matrix will live on
10588 .    seqmat - the input sequential matrices
10589 .    n - number of local columns (or PETSC_DECIDE)
10590 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10591 
10592    Output Parameter:
10593 .    mpimat - the parallel matrix generated
10594 
10595     Level: advanced
10596 
10597    Notes:
10598     The number of columns of the matrix in EACH processor MUST be the same.
10599 
10600 @*/
10601 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10602 {
10603   PetscErrorCode ierr;
10604 
10605   PetscFunctionBegin;
10606   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10607   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");
10608 
10609   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10610   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10611   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10612   PetscFunctionReturn(0);
10613 }
10614 
10615 /*@
10616      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10617                  ranks' ownership ranges.
10618 
10619     Collective on A
10620 
10621    Input Parameters:
10622 +    A   - the matrix to create subdomains from
10623 -    N   - requested number of subdomains
10624 
10625    Output Parameters:
10626 +    n   - number of subdomains resulting on this rank
10627 -    iss - IS list with indices of subdomains on this rank
10628 
10629     Level: advanced
10630 
10631     Notes:
10632     number of subdomains must be smaller than the communicator size
10633 @*/
10634 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10635 {
10636   MPI_Comm        comm,subcomm;
10637   PetscMPIInt     size,rank,color;
10638   PetscInt        rstart,rend,k;
10639   PetscErrorCode  ierr;
10640 
10641   PetscFunctionBegin;
10642   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10643   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10644   ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
10645   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);
10646   *n = 1;
10647   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10648   color = rank/k;
10649   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRMPI(ierr);
10650   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10651   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10652   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10653   ierr = MPI_Comm_free(&subcomm);CHKERRMPI(ierr);
10654   PetscFunctionReturn(0);
10655 }
10656 
10657 /*@
10658    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10659 
10660    If the interpolation and restriction operators are the same, uses MatPtAP.
10661    If they are not the same, use MatMatMatMult.
10662 
10663    Once the coarse grid problem is constructed, correct for interpolation operators
10664    that are not of full rank, which can legitimately happen in the case of non-nested
10665    geometric multigrid.
10666 
10667    Input Parameters:
10668 +  restrct - restriction operator
10669 .  dA - fine grid matrix
10670 .  interpolate - interpolation operator
10671 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10672 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10673 
10674    Output Parameters:
10675 .  A - the Galerkin coarse matrix
10676 
10677    Options Database Key:
10678 .  -pc_mg_galerkin <both,pmat,mat,none>
10679 
10680    Level: developer
10681 
10682 .seealso: MatPtAP(), MatMatMatMult()
10683 @*/
10684 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10685 {
10686   PetscErrorCode ierr;
10687   IS             zerorows;
10688   Vec            diag;
10689 
10690   PetscFunctionBegin;
10691   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10692   /* Construct the coarse grid matrix */
10693   if (interpolate == restrct) {
10694     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10695   } else {
10696     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10697   }
10698 
10699   /* If the interpolation matrix is not of full rank, A will have zero rows.
10700      This can legitimately happen in the case of non-nested geometric multigrid.
10701      In that event, we set the rows of the matrix to the rows of the identity,
10702      ignoring the equations (as the RHS will also be zero). */
10703 
10704   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10705 
10706   if (zerorows != NULL) { /* if there are any zero rows */
10707     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10708     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10709     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10710     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10711     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10712     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10713   }
10714   PetscFunctionReturn(0);
10715 }
10716 
10717 /*@C
10718     MatSetOperation - Allows user to set a matrix operation for any matrix type
10719 
10720    Logically Collective on Mat
10721 
10722     Input Parameters:
10723 +   mat - the matrix
10724 .   op - the name of the operation
10725 -   f - the function that provides the operation
10726 
10727    Level: developer
10728 
10729     Usage:
10730 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10731 $      ierr = MatCreateXXX(comm,...&A);
10732 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10733 
10734     Notes:
10735     See the file include/petscmat.h for a complete list of matrix
10736     operations, which all have the form MATOP_<OPERATION>, where
10737     <OPERATION> is the name (in all capital letters) of the
10738     user interface routine (e.g., MatMult() -> MATOP_MULT).
10739 
10740     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10741     sequence as the usual matrix interface routines, since they
10742     are intended to be accessed via the usual matrix interface
10743     routines, e.g.,
10744 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10745 
10746     In particular each function MUST return an error code of 0 on success and
10747     nonzero on failure.
10748 
10749     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10750 
10751 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10752 @*/
10753 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10754 {
10755   PetscFunctionBegin;
10756   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10757   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10758     mat->ops->viewnative = mat->ops->view;
10759   }
10760   (((void(**)(void))mat->ops)[op]) = f;
10761   PetscFunctionReturn(0);
10762 }
10763 
10764 /*@C
10765     MatGetOperation - Gets a matrix operation for any matrix type.
10766 
10767     Not Collective
10768 
10769     Input Parameters:
10770 +   mat - the matrix
10771 -   op - the name of the operation
10772 
10773     Output Parameter:
10774 .   f - the function that provides the operation
10775 
10776     Level: developer
10777 
10778     Usage:
10779 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10780 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10781 
10782     Notes:
10783     See the file include/petscmat.h for a complete list of matrix
10784     operations, which all have the form MATOP_<OPERATION>, where
10785     <OPERATION> is the name (in all capital letters) of the
10786     user interface routine (e.g., MatMult() -> MATOP_MULT).
10787 
10788     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10789 
10790 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10791 @*/
10792 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10793 {
10794   PetscFunctionBegin;
10795   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10796   *f = (((void (**)(void))mat->ops)[op]);
10797   PetscFunctionReturn(0);
10798 }
10799 
10800 /*@
10801     MatHasOperation - Determines whether the given matrix supports the particular
10802     operation.
10803 
10804    Not Collective
10805 
10806    Input Parameters:
10807 +  mat - the matrix
10808 -  op - the operation, for example, MATOP_GET_DIAGONAL
10809 
10810    Output Parameter:
10811 .  has - either PETSC_TRUE or PETSC_FALSE
10812 
10813    Level: advanced
10814 
10815    Notes:
10816    See the file include/petscmat.h for a complete list of matrix
10817    operations, which all have the form MATOP_<OPERATION>, where
10818    <OPERATION> is the name (in all capital letters) of the
10819    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10820 
10821 .seealso: MatCreateShell()
10822 @*/
10823 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10824 {
10825   PetscErrorCode ierr;
10826 
10827   PetscFunctionBegin;
10828   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10829   /* symbolic product can be set before matrix type */
10830   if (op != MATOP_PRODUCTSYMBOLIC) PetscValidType(mat,1);
10831   PetscValidPointer(has,3);
10832   if (mat->ops->hasoperation) {
10833     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10834   } else {
10835     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10836     else {
10837       *has = PETSC_FALSE;
10838       if (op == MATOP_CREATE_SUBMATRIX) {
10839         PetscMPIInt size;
10840 
10841         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
10842         if (size == 1) {
10843           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10844         }
10845       }
10846     }
10847   }
10848   PetscFunctionReturn(0);
10849 }
10850 
10851 /*@
10852     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10853     of the matrix are congruent
10854 
10855    Collective on mat
10856 
10857    Input Parameters:
10858 .  mat - the matrix
10859 
10860    Output Parameter:
10861 .  cong - either PETSC_TRUE or PETSC_FALSE
10862 
10863    Level: beginner
10864 
10865    Notes:
10866 
10867 .seealso: MatCreate(), MatSetSizes()
10868 @*/
10869 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10870 {
10871   PetscErrorCode ierr;
10872 
10873   PetscFunctionBegin;
10874   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10875   PetscValidType(mat,1);
10876   PetscValidPointer(cong,2);
10877   if (!mat->rmap || !mat->cmap) {
10878     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10879     PetscFunctionReturn(0);
10880   }
10881   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10882     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10883     if (*cong) mat->congruentlayouts = 1;
10884     else       mat->congruentlayouts = 0;
10885   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10886   PetscFunctionReturn(0);
10887 }
10888 
10889 PetscErrorCode MatSetInf(Mat A)
10890 {
10891   PetscErrorCode ierr;
10892 
10893   PetscFunctionBegin;
10894   if (!A->ops->setinf) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type");
10895   ierr = (*A->ops->setinf)(A);CHKERRQ(ierr);
10896   PetscFunctionReturn(0);
10897 }
10898