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